Android实战-忘记密码案例
需求描述
各家電商App的登陸頁面大同小異,要么是用戶名與密碼組合等等,要么是手機號碼和驗證碼組合登錄,若是做好一點的,則會提供找回密碼與記住密碼功能。先來看一下登錄頁面是什么樣,因為有兩種組合登陸方式,所以登陸頁面頁分成兩個效果圖。
從以上兩個登錄效果圖可以看到,密碼登錄與驗證碼登錄的界面主要存在一下幾點區別:
(1)密碼輸入框和驗證碼輸入框的左側標題以及輸入框內部的提示語各不相同。
(2)如果是密碼登錄,則需要支持找回密碼。如果是驗證碼登錄,則需要支持向用戶手機發送驗證碼。
(3)密碼登錄可以提供記住密碼的功能,而驗證碼每次的數值不一樣,無需也沒法記住驗證碼。
對于找回密碼功能,一般直接跳到找回密碼頁面,在該頁面輸入和確認新的密碼,并校驗找回密碼的合法性(通過短信驗證碼檢查),據此勾勒出密碼找回頁面的輪廓概貌,如下圖所示。
在找回密碼的操作過程中,為了更好地增強用戶體驗,有必要在幾個關鍵節點處提醒用戶。比如發送成功驗證碼之后,要及時提示用戶注意查收短信,這里暫且做成提醒對話框的形式。又比如密碼登錄成功之后,也要告知用戶已經修改成功登錄,注意繼續后面的操作。
界面設計
用戶登錄與找回密碼界面看似簡單,用到的控件卻不少。大致從上到下、從左到右分布著下列Android控件。1.單選按鈕RadioButton: 用來區分是密碼登錄和驗證碼登錄。2.文本視圖TextView: 輸入框左側要顯示此處應該輸入什么信息。3.編輯框EditText:用來輸入手機號碼、密碼和驗證碼。4.復選框CheckBox:用于判斷是否記住密碼。5.按鈕Button: 除了“登錄”按鈕,還要忘記密碼和獲取驗證碼兩個按鈕。6.線性布局LinearLayout:整體界面從上到下排列,用到了垂直方向的線性布局。7.相對布局:RelativeLayout:忘記密碼按鈕和密碼輸入框是疊加的。且“忘記密碼”與上級視圖右對齊。8.單選組RadioGroup:密碼登錄和驗證碼登錄這兩個單選按鈕,需要放在單選組之中。9.提醒對話框AlertDialog:為了演示方便,獲取驗證碼與登陸成功都通過提醒對話框向用戶反饋結果。另外,整個登錄模塊是由登錄頁面和找回密碼頁面組成,因此這兩個頁面之間要進行數據交互,也就是在頁面跳轉之時傳遞參數。譬如,從登錄頁面跳到找回密碼界面,要攜帶唯一地標識的手機號碼作為請求參數,不然找回密碼界面不知道要給哪個手機號碼修改密碼。同時,從找回密碼頁面回到登錄頁面,也要將修改之后的新密碼作為應答參數傳出去,否則登錄頁面不知道密碼被改成什么了。注意事項
ViewUtil.java
package com.example.retrievepassword.util;import android.app.Activity; import android.content.Context; import android.view.View; import android.view.inputmethod.InputMethodManager;public class ViewUtil {public static void hideAllInputMethod(Activity act) {// 從系統服務中獲取輸入法管理器InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);if (imm.isActive()) { // 軟鍵盤如果已經打開則關閉之imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);}}public static void hideOneInputMethod(Activity act, View v) {// 從系統服務中獲取輸入法管理器InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);// 關閉屏幕上的輸入法軟鍵盤imm.hideSoftInputFromWindow(v.getWindowToken(), 0);}}action_login_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="5dp"><RadioGroupandroid:id="@+id/rg_login"android:layout_width="match_parent"android:layout_height="50dp"android:orientation="horizontal"><RadioButtonandroid:id="@+id/rb_password"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:checked="true"android:gravity="left|center"android:text="密碼登錄"android:textColor="@color/black"android:textSize="17sp"/><RadioButtonandroid:id="@+id/rb_verifycode"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:checked="false"android:gravity="left|center"android:text="驗證碼登錄"android:textColor="@color/black"android:textSize="17sp"/></RadioGroup><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"><TextViewandroid:id="@+id/tv_phone"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="手機號碼"android:textColor="@color/black"android:textSize="17sp"/><EditTextandroid:id="@+id/et_phone"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginBottom="5dp"android:layout_marginTop="5dp"android:layout_toRightOf="@+id/tv_phone"android:background="@drawable/editable_selector"android:gravity="left|center"android:hint="請輸入手機號碼"android:inputType="number"android:maxLength="11"android:textColor="@color/black"android:textSize="17sp"android:textColorHint="@color/grey"/></RelativeLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"><TextViewandroid:id="@+id/tv_password"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="登錄密碼:"android:textColor="@color/black"android:textSize="17sp"/><RelativeLayoutandroid:id="@+id/et_password"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginBottom="5dp"android:layout_marginTop="5dp"android:background="@drawable/editable_selector"android:gravity="left|center"android:hint="請輸入密碼"android:inputType="numberPassword"android:maxLength="6"android:textColor="@color/black"android:textColorHint="@color/grey"android:textSize="17sp"><Buttonandroid:id="@+id/btn_forget"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="忘記密碼"android:textColor="@color/black"android:textSize="17sp"/></RelativeLayout></RelativeLayout><CheckBoxandroid:id="@+id/ck_remember"android:layout_width="match_parent"android:layout_height="wrap_content"android:button="@drawable/checkbox_selector"android:checked="false"android:padding="10dp"android:text="記住密碼"android:textColor="@color/black"android:textSize="17sp"/><Buttonandroid:id="@+id/btn_login"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="登錄"android:textColor="@color/black"android:textSize="20sp"/></LinearLayout>LoginMainActivity.java
package com.example.retrievepassword;import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import com.example.retrievepassword.util.ViewUtil;import java.util.Random;@SuppressLint("DefaultLocale") public class LoginMainActivity extends AppCompatActivity implements View.OnClickListener {private RadioGroup rg_login;//聲明一個單選組對象private RadioButton rb_password;//聲明一個單選按鈕對象private RadioButton rb_verifycode;//聲明一個單選按鈕按鈕對象private EditText et_phone;//聲明一個編輯框對象private TextView tv_password;//聲明一個文本視圖對象private EditText et_password;//聲明一個編輯狂對象private Button btn_forget;//聲明一個按鈕控件對象private CheckBox ck_remember;//聲明一個復選框對象private int mRequestCode = 0;//跳轉頁面時的請求常量private boolean isRemember = false;//是否記住密碼private String mPassword = "111111";//默認密碼private String mVerifyCode;//驗證碼@SuppressLint("WrongViewCast")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login_main);rg_login = findViewById(R.id.rg_login);rb_password = findViewById(R.id.rb_password);rb_verifycode = findViewById(R.id.rb_verifycode);et_phone=findViewById(R.id.et_phone);tv_password=findViewById(R.id.tv_password);et_password=findViewById(R.id.et_password);btn_forget = findViewById(R.id.btn_forget);ck_remember = findViewById(R.id.ck_remember);//設置監聽器rg_login.setOnCheckedChangeListener(new RadioListener());//監聽按鈕組改變ck_remember.setOnCheckedChangeListener(new CheckListener());//監聽記住密碼復選框et_phone.addTextChangedListener(new HideTextWatcher(et_phone,11));//監聽手機號碼輸入框的文本改變et_password.addTextChangedListener(new HideTextWatcher(et_password,6));//監聽登錄密碼輸入框的改變btn_forget.setOnClickListener(this);//監聽忘記密碼按鈕的點擊事件findViewById(R.id.btn_login).setOnClickListener(this);//監聽登錄按鈕的點擊事件}//定義登錄方式的單選監聽器private class RadioListener implements RadioGroup.OnCheckedChangeListener {@Overridepublic void onCheckedChanged(RadioGroup group,int checkId) {if(checkId == R.id.rb_password) { //選擇了密碼登錄tv_password.setText("登錄密碼: ");et_password.setHint("請輸入密碼");btn_forget.setText("記住密碼");ck_remember.setVisibility(View.VISIBLE);} else if(checkId == R.id.rb_verifycode) {tv_password.setText("驗證碼:");et_password.setHint("請輸入驗證碼:");btn_forget.setText("獲取驗證碼:");ck_remember.setVisibility(View.GONE);}}}//定義是否記住密碼的監聽器private class CheckListener implements CompoundButton.OnCheckedChangeListener {@Overridepublic void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {if(buttonView.getId() == R.id.ck_remember) {isRemember = isChecked;}}}//定義一個編輯框監聽器,再輸入文本達到指定長度時自動隱藏輸入法private class HideTextWatcher implements TextWatcher {private EditText mView;//聲明一個編輯框對象private int mMaxLength;//聲明一個最大長度變量public HideTextWatcher(EditText v,int maxLength) {super();mView = v;mMaxLength = maxLength;}// 在編輯框的輸入文本變化前觸發public void beforeTextChanged(CharSequence s, int start, int count, int after) {}// 在編輯框的輸入文本變化時觸發public void onTextChanged(CharSequence s, int start, int before, int count) {}// 在編輯框的輸入文本變化后觸發public void afterTextChanged(Editable s) {String str = s.toString();//獲得已輸入的文本字符串//輸入文本達到11位(如手機號碼)或者達到6位,如登錄密碼時關閉輸入法if((str.length() == 11 && mMaxLength == 11) || (str.length() == 6 && mMaxLength == 6)) {ViewUtil.hideOneInputMethod(LoginMainActivity.this,mView);}}}@Overridepublic void onClick(View v) {String phone = et_phone.getText().toString();if(v.getId() == R.id.btn_forget) //點擊了忘記密碼按鈕{if(phone.length() < 11) {//手機號碼長度不足11位Toast.makeText(this,"請輸入正確的手機號",Toast.LENGTH_SHORT).show();return;}if(rb_password.isChecked()) {//選擇了密碼方式校驗,此時要跳轉到找回密碼界面Intent intent = new Intent(this,LoginForgetActivity.class);intent.putExtra("phone",phone);startActivityForResult(intent,mRequestCode);//攜帶意圖返回上一個頁面} else if(rb_verifycode.isChecked()) {//選擇了驗證碼方式校驗,提示用戶記住六位驗證碼數字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.length() < 11) {//手機號碼不足11位Toast.makeText(this,"請輸入正確的手機號",Toast.LENGTH_SHORT).show();}if(rb_password.isChecked()) {//密碼方式校驗if(!et_password.getText().toString().equals(mPassword)) {Toast.makeText(this,"請輸入正確的密碼",Toast.LENGTH_SHORT).show();} else {//密碼校驗通過loginSuccess();//提示用戶登錄成功}} else if(rb_verifycode.isChecked()) {//驗證碼方式校驗if(!et_password.getText().toString().equals(mVerifyCode)) {Toast.makeText(this,"請輸入正確的驗證碼",Toast.LENGTH_SHORT).show();} else {//驗證碼校驗通過loginSuccess();//提示用戶登錄成功}}}}//從下一個頁面攜帶參數返回當前頁面時觸發@Overrideprotected void onActivityResult(int requestCode,int resultCode,Intent data) {super.onActivityResult(requestCode,resultCode,data);if(requestCode == mRequestCode && data != null) {//用戶密碼已經改為新的密碼,故更新密碼變量mPassword = data.getStringExtra("new_password");}}//從修改密碼頁面返回登錄頁面,要清空密碼的輸入框@Overrideprotected void onRestart() {super.onRestart();et_password.setText("");}//校驗通過,登錄成功private void loginSuccess() {String desc = String.format("您的手機號碼是:%s,恭喜您通過登錄驗證,點擊確定按鈕返回上個頁面",et_phone.getText().toString());//以下彈出提醒對話框,提示用戶登錄成功AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("登錄成功");builder.setMessage(desc);builder.setPositiveButton("確定返回", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {finish();//結束當前活動頁面}});builder.setNegativeButton("我再看看",null);AlertDialog alert = builder.create();alert.show();//顯示提醒對話框} }activity_login_forget.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="5dp"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"><TextViewandroid:id="@+id/tv_password_first"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="輸入新密碼:"android:textColor="@color/black"android:textSize="17sp"/><EditTextandroid:id="@+id/et_password_first"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginBottom="5dp"android:layout_marginTop="5dp"android:layout_toRightOf="@+id/tv_password_first"android:background="@drawable/editext_selector"android:gravity="left|center"android:hint="請輸入新密碼"android:inputType="numberPassword"android:maxLength="11"android:textColor="@color/black"android:textColorHint="@color/grey"android:textSize="17sp"/></RelativeLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp" ><TextViewandroid:id="@+id/tv_password_second"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="確認新密碼:"android:textColor="@color/black"android:textSize="17sp" /><EditTextandroid:id="@+id/et_password_second"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginBottom="5dp"android:layout_marginTop="5dp"android:layout_toRightOf="@+id/tv_password_second"android:background="@drawable/editext_selector"android:gravity="left|center"android:hint="請再次輸入新密碼"android:inputType="numberPassword"android:maxLength="11"android:textColor="@color/black"android:textColorHint="@color/grey"android:textSize="17sp" /></RelativeLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp" ><TextViewandroid:id="@+id/tv_verifycode"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text=" 驗證碼:"android:textColor="@color/black"android:textSize="17sp" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_toRightOf="@+id/tv_verifycode" ><EditTextandroid:id="@+id/et_verifycode"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginBottom="5dp"android:layout_marginTop="5dp"android:background="@drawable/editext_selector"android:gravity="left|center"android:hint="請輸入驗證碼"android:inputType="numberPassword"android:maxLength="6"android:textColor="@color/black"android:textColorHint="@color/grey"android:textSize="17sp" /><Buttonandroid:id="@+id/btn_verifycode"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_alignParentRight="true"android:gravity="center"android:text="獲取驗證碼"android:textColor="@color/black"android:textSize="17sp" /></RelativeLayout></RelativeLayout><Buttonandroid:id="@+id/btn_confirm"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="確 定"android:textColor="@color/black"android:textSize="20sp" /> </LinearLayout>colors.xml
<?xml version="1.0" encoding="utf-8"?> <resources><color name="purple_200">#FFBB86FC</color><color name="purple_500">#FF6200EE</color><color name="purple_700">#FF3700B3</color><color name="teal_200">#FF03DAC5</color><color name="teal_700">#FF018786</color><color name="colorPrimary">#008577</color><color name="colorPrimaryDark">#00574B</color><color name="colorAccent">#D81B60</color><color name="black">#000000</color><color name="white">#ffffff</color><color name="grey">#cccccc</color> </resources>checkbox_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_checked="true" android:drawable="@drawable/check_choose"></item><item android:drawable="@drawable/check_unchoose"></item> </selector>editable_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_focused="true" android:drawable="@drawable/shape_edit_focus"></item><item android:drawable="@drawable/shape_edit_normal"></item> </selector>editext_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_focused="true" android:drawable="@drawable/shape_edit_focus"></item><item android:drawable="@drawable/shape_edit_normal"></item> </selector>shape_edit_focus.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="#ffffff"/><stroke android:width="1dp" android:color="#00ffff"/><corners android:radius="5dp"/><padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp"/> </shape>shape_edit_normal.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="#ffffff"/><stroke android:width="1dp"/><corners android:radius="5dp"/><pading android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp"/> </shape>利用共享參數實現記住密碼功能
(1)聲明一個共享參數對象,并在onCreate中調用getSharedPreferences方法獲取共享參數的實例。
(2)登錄成功時,如果用戶勾選了“記住密碼”,就使用共享參數保存手機號碼與密碼,也就是在loginSuccess方法中增加代碼.
總結
以上是生活随笔為你收集整理的Android实战-忘记密码案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯地图JavaScript API G
- 下一篇: Drools WorkBench的简介与