官术网_书友最值得收藏!

3.6 實戰項目:登錄App

現在是實戰項目時間,大家如此費力地看書學習,還不就是為了在實際項目中派上用場。凡是賺錢的App,都要掌握用戶資源,這便少不了為用戶提供登錄頁面。下面設計并實現App的登錄功能。

3.6.1 設計思路

如今樓市瘋狂上漲,要買房自然少不了房貸,根據不同的貸款方式與還款方式計算出的月供數額各不相同。如果手機上有房貸計算器,就會便利許多。房貸計算器絕對是一個方便實用的App,本書迄今為止介紹的App開發知識足夠寫一個房貸計算器App了,如圖3-26所示。本章學到的主要控件基本都能派上用場,包括RelativeLayout、EditText、RadioButton、CheckBox、Spinner等。讀者若有興趣可自行編碼練習,補充房貸計算的具體業務邏輯。

圖3-26 房貸計算器的效果圖

本章的實戰項目最終選定App登錄頁面,是因為要復習Activity的相關概念與用法。Activity是Android中最常用的組件,后續章節全部都會用到,所以要好好加以鞏固。

各家App的登錄頁面大同小異,要么是用戶名與密碼組合登錄,要么是手機號與驗證碼組合登錄,如果要做得更好一點,就要提供忘記密碼與記住密碼等功能。我們的App登錄項目把這些功能綜合一下,都呈現到頁面上,因為是練手,所以盡量讓學到的控件都派上用場。登錄頁面的設計圖初稿如圖3-27所示。

圖3-27 登錄頁面的效果圖

讀者找找看這個效果圖包含哪些本章的新控件?一定會發現以下6個控件。

● 單選按鈕RadioButton:用來區分是密碼登錄還是驗證碼登錄。

● 下拉框Spinner:用于區分用戶類型是個人用戶還是公司用戶。

● 編輯框EditText:用來輸入手機號碼和密碼。

● 復選框CheckBox:用于判斷是否記住密碼。

● 相對布局RelativeLayout:指定手機號碼的編輯框放在手機號碼TextView的右邊。這里使用線性布局LinearLayout也可以。

● 框架布局FrameLayout:忘記密碼的按鈕與密碼輸入框疊加。

至此,本章介紹的新控件基本都派上用場了。另外,本項目還要演示活動頁面的的跳轉功能,點擊“忘記密碼”按鈕跳轉到找回密碼頁面,找回密碼頁面的效果如圖3-28所示。

圖3-28 找回密碼頁面的效果圖

找回密碼的頁面挺簡單,主要問題是兩個頁面之間的跳轉有哪些注意事項?頁面跳轉肯定要傳遞參數,一般唯一標識的手機號碼要傳過去,不然下一個頁面不知道要為哪個手機號碼修改密碼;新密碼也要傳回去,不然上一個頁面不知道密碼被改成什么了。

另外,有一個細微的用戶體驗問題:用戶會去找回密碼,肯定是發現輸入的密碼不對。修改完密碼回到登錄頁面時,密碼輸入框里還是原來錯誤的密碼,此時用戶清空錯誤密碼才能輸入新密碼。我們的App想讓用戶覺得好用,就得急用戶之所急、想用戶之所想,像之前錯誤密碼的情況應當由App在返回登錄頁面時自動清空原來錯誤的密碼。自動清空的操作放在onActivityResult方法中處理是一個辦法,但這樣處理有一個問題,如果用戶直接按返回鍵回到登錄頁面,onActivityResult方法發現數據為空就不會處理。

這個問題其實不難,只要認真看書,結合前面關于Activity生命周期的說明,就能夠找到解決辦法。重寫onRestart方法(確保是返回頁面),在方法內部加上清空密碼框的處理即可。這樣一來,無論用戶是修改完密碼回到登錄頁,還是點擊返回鍵回到登錄頁,App都會自動清空密碼框。

3.6.2 小知識:提醒對話框AlertDialog

使用驗證碼登錄時,App要向用戶手機發送短信驗證碼,但發送短信需要服務器支持,所以這里暫時使用隨機數模擬驗證碼,然后以對話框的形式在界面上提示用戶。另外,在登錄的過程中,App時常需要彈窗提示用戶選擇“是”或“否”,以此判斷下一步的處理邏輯。在本實戰項目開始之前,建議讀者先演練一下提醒對話框(AlertDialog)的用法。

AlertDialog是Android中最常用的對話框,可以完成常見的交互操作,如提示、確認、選擇等功能。AlertDialog沒有公開的構造函數,必須借助AlertDialog.Builder才能完成參數設置,AlertDialog.Builder的常用方法如下。

● setIcon:設置標題的圖標。

● setTitle:設置標題的文本。

● setMessage:設置內容的文本。

● setPositiveButton:設置肯定按鈕的信息,包括按鈕文本和點擊監聽器。

● setNegativeButton:設置否定按鈕的信息,包括按鈕文本和點擊監聽器。

● setNeutralButton:設置中性按鈕的信息,包括按鈕文本和點擊監聽器,該方法比較少用。

通過AlertDialog.Builder設置完參數,還需調用create方法才能生成AlertDialog對象。最后調用AlertDialog對象的show方法,在頁面上彈出提醒對話框。

下面是個提醒對話框的代碼:

            public void onClick(View v) {
                if (v.getId() == R.id.btn_alert) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("尊敬的用戶");
                    builder.setMessage("你真的要卸載我嗎?");
                    builder.setPositiveButton("殘忍卸載", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            tv_alert.setText("雖然依依不舍,但是只能離開了");
                        }
                    });
                    builder.setNegativeButton("我再想想", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            tv_alert.setText("讓我再陪你三百六十五個日夜");
                        }
                    });
                    AlertDialog alert = builder.create();
                    alert.show();
                }
            }

提醒對話框的彈窗效果如圖3-29所示,該對話框有標題、有內容,還有兩個按鈕。

圖3-29 AlertDialog的效果圖

用戶點擊不同的按鈕會觸發不同的處理邏輯。圖3-30所示為點擊“我再想想”按鈕后的頁面,圖3-31所示為點擊“殘忍卸載”按鈕后的頁面。

圖3-30 點擊“我再想想”的截圖

圖3-31 點擊“殘忍卸載”的截圖

3.6.3 代碼示例

前面的設計不但給出了兩個頁面的效果圖,而且給出了業務邏輯的大概思路,接下來主要是編碼將其實現。編碼過程分為3個步驟:

步驟01 先想好代碼文件與布局文件的名稱,比如登錄頁面的代碼文件取名LoginMainActivity.java,布局文件取名activity_login.xml;找回密碼頁面的代碼文件取名LoginForgetActivity.java,布局文件取名activity_login_forget.xml。記得在AndroidManifest.xml中注冊兩個頁面的acitivity節點,注冊代碼如下:

              <activity android:name=".LoginMainActivity" />
              <activity android:name=".LoginForgetActivity" />

步驟02 在res/layout目錄下創建布局文件activity_login.xml和activity_login_forget.xml,根據頁面效果圖編寫兩個頁面的布局定義文件。

步驟03 在項目的包名目錄下創建類LoginMainActivity和LoginForgetActivity,填入具體的控件操作與業務邏輯代碼。

下面是登錄頁面LoginMainActivity.java的主要代碼片段:

            public void onClick(View v) {
                String phone = et_phone.getText().toString();
                if (v.getId() == R.id.btn_forget) {
                    if (phone==null || phone.length()<11) {
                        Toast.makeText(this, "請輸入正確的手機號", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (rb_password.isChecked() == true) {
                        Intent intent = new Intent(this, LoginForgetActivity.class);
                        intent.putExtra("phone", phone);
                        startActivityForResult(intent, mRequestCode);
                    } else if (rb_verifycode.isChecked() == true) {
                        mVerifyCode = String.format("%06d", (int)(Math.random()*1000000%1000000));
                        AlertDialog.Builder builder = new AlertDialog.Builder(this);
                        builder.setTitle("請記住驗證碼");
                        builder.setMessage("手機號"+phone+",本次驗證碼是"+mVerifyCode+",請輸入驗證碼");
                        builder.setPositiveButton("好的", null);
                        AlertDialog alert = builder.create();
                        alert.show();
                    }
                } else if (v.getId() == R.id.btn_login) {
                    if (phone==null || phone.length()<11) {
                        Toast.makeText(this, "請輸入正確的手機號", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (rb_password.isChecked() == true) {
                        if (et_password.getText().toString().equals(mPassword) ! = true) {
                            Toast.makeText(this, "請輸入正確的密碼", Toast.LENGTH_SHORT).show();
                            return;
                        } else {
                            loginSuccess();
                        }
                    } else if (rb_verifycode.isChecked() == true) {
                        if (et_password.getText().toString().equals(mVerifyCode) ! = true) {
                            Toast.makeText(this, "請輸入正確的驗證碼", Toast.LENGTH_SHORT).show();
                            return;
                        } else {
                            loginSuccess();
                        }
                    }
                }
            }
            @Override
            protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                if (requestCode == mRequestCode && data! =null) {
                    //用戶密碼已改為新密碼
                    mPassword = data.getStringExtra("new_password");
                }
            }
            //從修改密碼頁面返回登錄頁面,要清空密碼的輸入框
            @Override
            protected void onRestart() {
                et_password.setText("");
                super. onRestart();
            }


            private void loginSuccess() {
                String desc = String.format("您的手機號碼是%s,類型是%s。恭喜你通過登錄驗證,點擊“確
    定”按鈕返回上個頁面", et_phone.getText().toString(), typeArray[mType]);
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("登錄成功");
                builder.setMessage(desc);
                builder.setPositiveButton("確定返回", new DialogInterface.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which){
                        finish();
                    }
                });
                builder.setNegativeButton("我再看看", null);
                AlertDialog alert=builder.create();
                alert.show();
            }

下面是找回密碼頁面LoginForgetActivity.java的代碼:

    public class LoginForgetActivity extends AppCompatActivity implements OnClickListener {
        private EditText et_password_first;
        private EditText et_password_second;
        private EditText et_verifycode;
        private String mVerifyCode;
        private String mPhone;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_login_forget);
            et_password_first = (EditText) findViewById(R.id.et_password_first);
            et_password_second = (EditText) findViewById(R.id.et_password_second);
            et_verifycode = (EditText) findViewById(R.id.et_verifycode);
            findViewById(R.id.btn_verifycode).setOnClickListener(this);
            findViewById(R.id.btn_confirm).setOnClickListener(this);
            mPhone = getIntent().getStringExtra("phone");
        }
        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.btn_verifycode) {
                if (mPhone==null || mPhone.length()<11) {
                    Toast.makeText(this, "請輸入正確的手機號", Toast.LENGTH_SHORT).show();
                    return;
                }
                mVerifyCode = String.format("%06d", (int) (Math.random() * 1000000 % 1000000));
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("請記住驗證碼");
                builder.setMessage("手機號"+mPhone+",本次驗證碼是"+mVerifyCode+",請輸入驗證碼");
                builder.setPositiveButton("好的", null);
                    AlertDialog alert = builder.create();
                    alert.show();
                } else if (v.getId() == R.id.btn_confirm) {
                    String password_first = et_password_first.getText().toString();
                    String password_second = et_password_second.getText().toString();
                    if (password_first==null || password_first.length()<6 ||
                            password_second==null || password_second.length()<6) {
                        Toast.makeText(this, "請輸入正確的新密碼", Toast.LENGTH_SHORT).show();
                        return;
                    } else if (password_first.equals(password_second) ! = true) {
                        Toast.makeText(this, "兩次輸入的新密碼不一致", Toast.LENGTH_SHORT).show();
                        return;
                    } else if (et_verifycode.getText().toString().equals(mVerifyCode) ! = true) {
                        Toast.makeText(this, "請輸入正確的驗證碼", Toast.LENGTH_SHORT).show();
                        return;
                    } else {
                        Toast.makeText(this, "密碼修改成功", Toast.LENGTH_SHORT).show();
                        Intent intent = new Intent();
                        intent.putExtra("new_password", password_first);
                        setResult(Activity.RESULT_OK, intent);
                        finish();
                    }
                }
            }
        }
主站蜘蛛池模板: 边坝县| 治县。| 甘孜县| 海晏县| 班玛县| 高雄市| 中西区| 巴林左旗| 达孜县| 山阴县| 茌平县| 宜春市| 南投市| 平利县| 鄂温| 南部县| 阿克苏市| 紫阳县| 庆云县| 肥乡县| 福贡县| 彭山县| 临沭县| 唐海县| 新乡县| 南木林县| 政和县| 贵德县| 肃北| 伊春市| 荥经县| 平遥县| 读书| 武川县| 黄梅县| 绿春县| 晋城| 黎城县| 伽师县| 灌云县| 南昌县|