Android程序開發(fā)之防止密碼輸入錯(cuò)誤 密碼明文顯示功能
在使用App的時(shí)候,首次登錄都需要用戶輸入密碼的,有些朋友為了安全起見密碼設(shè)置的比較長(zhǎng),導(dǎo)致很多次密碼都輸入錯(cuò)誤,嚴(yán)重影響了用戶體驗(yàn)效果。這一點(diǎn)移動(dòng)開發(fā)者做好了準(zhǔn)備工作,因?yàn)槭謾C(jī)的私密性比較強(qiáng),在輸入密碼的時(shí)候,可以顯示輸入,增強(qiáng)準(zhǔn)確性,提升用戶體驗(yàn)度。這當(dāng)然要付出代價(jià)的,需要額外的代碼編寫功能。下面通過本文給大家介紹如何編寫密碼明文顯示的功能,僅供參考。

本文源碼的GitHub下載地址
要點(diǎn)
(1) 重寫EditText, 添加提示密碼顯示和隱藏的圖片.
(2) 判斷點(diǎn)擊位置, 切換EditText的密碼顯示狀態(tài).
(3) 在屏幕旋轉(zhuǎn)或配置改變時(shí), 保留圖片的狀態(tài)信息.
實(shí)現(xiàn)只有一個(gè)類和兩個(gè)圖片資源, 大家可以自由定制.
1. 布局樣式
兩種密碼的顯示樣式, 一種是常規(guī)顯示, 一種是TextInputLayout顯示.
<LinearLayout android:id="@+id/main_ll_container_1" android:layout_width="match_parent" android:layout_height="40dp" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密碼:" android:textSize="20sp"/> <me.chunyu.spike.wcl_password_input_demo.PasswordEditText android:id="@+id/main_pet_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:hint="請(qǐng)輸入密碼"/> </LinearLayout> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/main_ll_container_1"> <me.chunyu.spike.wcl_password_input_demo.PasswordEditText android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:hint="請(qǐng)輸入密碼"/> </android.support.design.widget.TextInputLayout>
效果

2. 提示圖標(biāo)
初始化資源和布局, 獲取密碼圖片的資源, 監(jiān)聽EditText, 有文字時(shí)顯示圖標(biāo), 沒有文字時(shí)隱藏圖標(biāo).
// 初始化布局
public void initFields(AttributeSet attrs, int defStyleAttr) {
if (attrs != null) {
// 獲取屬性信息
TypedArray styles = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.PasswordEditText, defStyleAttr, 0);
try {
// 根據(jù)參數(shù), 設(shè)置Icon
mShowPwdIcon = styles.getResourceId(R.styleable.PasswordEditText_pet_iconShow, mShowPwdIcon);
mHidePwdIcon = styles.getResourceId(R.styleable.PasswordEditText_pet_iconHide, mHidePwdIcon);
} finally {
styles.recycle();
}
}
// 密碼狀態(tài)
setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() > 0) {
// 有文字時(shí)顯示指示器
showPasswordVisibilityIndicator(true);
} else {
mIsShowPwdIcon = false;
restorePasswordIconVisibility(mIsShowPwdIcon);
showPasswordVisibilityIndicator(false); // 隱藏指示器
}
}
@Override public void afterTextChanged(Editable s) {
}
});
}
setInputType設(shè)置密碼狀態(tài), TYPE_TEXT_VARIATION_PASSWORD密文狀態(tài).
通過pet_iconShow屬性, 可以選擇自定義密碼提示圖片.
3. 監(jiān)聽事件
點(diǎn)擊圖片, 切換顯示或隱藏密碼, 獲取點(diǎn)擊位置, 和圖片位置進(jìn)行比較, 判斷事件.
@Override public boolean onTouchEvent(MotionEvent event) {
if (mDrawableSide == null) {
return super.onTouchEvent(event);
}
final Rect bounds = mDrawableSide.getBounds();
final int x = (int) event.getRawX(); // 點(diǎn)擊的位置
int iconX = (int) getTopRightCorner().x;
// Icon的位置
int leftIcon = iconX - bounds.width();
Log.e(TAG, "x: " + x + ", leftIcon: " + leftIcon);
// 大于Icon的位置, 才能觸發(fā)點(diǎn)擊
if (x >= leftIcon) {
togglePasswordIconVisibility(); // 變換狀態(tài)
event.setAction(MotionEvent.ACTION_CANCEL);
return false;
}
return super.onTouchEvent(event);
}
切換明文或密文的密碼
// 設(shè)置密碼指示器的狀態(tài)
private void restorePasswordIconVisibility(boolean isShowPwd) {
if (isShowPwd) {
// 可視密碼輸入
setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
} else {
// 非可視密碼狀態(tài)
setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
}
// 移動(dòng)光標(biāo)
setSelection(getText().length());
}
4. 保存狀態(tài)
重寫SavedState, 在旋轉(zhuǎn)屏幕時(shí), 保存和恢復(fù)顯示圖片信息.
// 存儲(chǔ)密碼狀態(tài), 顯示Icon的位置
protected static class PwdSavedState extends BaseSavedState {
private final boolean mShowingIcon;
private PwdSavedState(Parcelable superState, boolean showingIcon) {
super(superState);
mShowingIcon = showingIcon;
}
private PwdSavedState(Parcel in) {
super(in);
mShowingIcon = in.readByte() != 0;
}
public boolean isShowingIcon() {
return mShowingIcon;
}
@Override
public void writeToParcel(Parcel destination, int flags) {
super.writeToParcel(destination, flags);
destination.writeByte((byte) (mShowingIcon ? 1 : 0));
}
public static final Parcelable.Creator<PwdSavedState> CREATOR = new Creator<PwdSavedState>() {
public PwdSavedState createFromParcel(Parcel in) {
return new PwdSavedState(in);
}
public PwdSavedState[] newArray(int size) {
return new PwdSavedState[size];
}
};
}
動(dòng)畫效果

現(xiàn)在可以把類復(fù)制到應(yīng)用中, 更換圖片資源, 替換顯示密碼框, 給用戶更好的移動(dòng)端體驗(yàn). 永遠(yuǎn)追求極致, 追求不凡.
關(guān)于Android程序開發(fā)之防止密碼輸入錯(cuò)誤 密碼明文顯示功能的相關(guān)知識(shí)就給大家介紹到這里,希望對(duì)大家有所幫助!
相關(guān)文章
Android網(wǎng)絡(luò)編程之UDP通信模型實(shí)例
這篇文章主要介紹了Android網(wǎng)絡(luò)編程之UDP通信模型實(shí)例,本文給出了服務(wù)端代碼和客戶端代碼,需要的朋友可以參考下2014-10-10
Android音樂播放器制作 點(diǎn)擊歌曲實(shí)現(xiàn)播放(二)
這篇文章主要為大家詳細(xì)介紹了Android音樂播放器的制作方法,點(diǎn)擊歌曲實(shí)現(xiàn)播放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
Android編程之ICS式下拉菜單PopupWindow實(shí)現(xiàn)方法詳解(附源碼下載)
這篇文章主要介紹了Android編程之ICS式下拉菜單PopupWindow實(shí)現(xiàn)方法,結(jié)合實(shí)例詳細(xì)分析了ICS式下拉菜單的實(shí)現(xiàn)原理與相關(guān)技巧,并附帶源碼供讀者下載,需要的朋友可以參考下2015-12-12
Android通過Webservice操作sqlserver數(shù)據(jù)庫實(shí)例代碼
這篇文章主要介紹了Android通過Webservice操作sqlserver數(shù)據(jù)庫的相關(guān)知識(shí),對(duì)webservice操作數(shù)據(jù)庫相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01
使用ViewPager實(shí)現(xiàn)android軟件使用向?qū)Чδ軐?shí)現(xiàn)步驟
現(xiàn)在的大部分android軟件,都是使用說明,就是第一次使用該軟件時(shí),會(huì)出現(xiàn)向?qū)?,可以左右滑?dòng),然后就進(jìn)入應(yīng)用的主界面了,下面我們就實(shí)現(xiàn)這個(gè)功能2013-11-11
android 9.0 launcher3 去掉抽屜式顯示所有 app(代碼詳解)
本文通過實(shí)例代碼給大家介紹了android 9.0 Launcher3 去掉抽屜式,顯示所有 app,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11
android開發(fā)實(shí)現(xiàn)列表控件滾動(dòng)位置精確保存和恢復(fù)的方法(推薦)
下面小編就為大家?guī)硪黄猘ndroid開發(fā)實(shí)現(xiàn)列表控件滾動(dòng)位置精確保存和恢復(fù)的方法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03

