EditText 的那些事兒(一)
針對EditText 的相關知識點整理一下,主要有EditText的相關屬性,EditText的自定義VIew方面以及連帶的其他知識點;一為EditText的相關屬性及連帶知識點,後面寫寫自定義view繼承EditText, 比如密碼輸入框(帶刪除,明文暗文按鈕),更強大的autoCompletTextView.
監聽佈局變化
場景:對於一些登陸介面,在輸入密碼和賬號的時候,當軟鍵盤彈出來的時候,需要把密碼賬號輸入框向上移動?讓使用者輸入的位置始終位於螢幕中間往上一點的位置;
插入圖片:
思路
通過監聽跟佈局變化 rootView.getViewTreeObserver().addOnGlobalLayoutListener 來實現,然後佈局最外面通過scollview包裹起來,清單檔案中的activity的加上 android:windowSoftInputMode="adjustResize" 。
步驟如下:
先在佈局載入完後,用非同步獲取剛開始軟鍵盤沒有彈出來的時候高度。在動態監聽佈局的變化並作出相應的改變;
其核心程式碼如下:
非同步獲取開始控制元件座標:
new Handler().post(new Runnable() { @Override public void run() { mInputHeightInScreen = getViewYLocationInScreeen(mAccountNameEdt); LogUtil.debugLog(TAG, "initWidget: " + mInputHeightInScreen); } });
對使用者產生互動後的佈局進行監聽:
// 這裡的rootView 可以是最外層佈局scrollView 或者 setContentView 中的view // 以及那個fragment中的那個inflater 打包的view; rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect rect = new Rect(); rootView.getWindowVisibleDisplayFrame(rect); int mainInvisibleHeight = rootView.getRootView().getHeight() - rect.bottom; int screenHeight = rootView.getRootView().getHeight(); if (mainInvisibleHeight > screenHeight / 4){ int[] location = new int[2]; mSubmitBtn.getLocationInWindow(location); final int scrollHeight = location[1] + mSubmitBtn.getHeight() - rect.bottom; LogUtil.debugLog(TAG, "location[1]為:" + location[1] + ",scrollHeight為" + scrollHeight + ", rect.bottom為" + rect.bottom + "mainInvisibleHeight:" + mainInvisibleHeight); if (mAccountNameEdt.isFocused()){ mScrolView.scrollTo(0 , getViewYLocationInScreeen(mAccountNameEdt) - mInputHeightInScreen ); } else if (mFirstNameEdt.isFocused()){ mScrolView.scrollTo(0 , 150); }else if (mLastNameEdt.isFocused()){ mScrolView.scrollTo(0 , 300); }else if (mAccountPasswordEdt.isFocused()){ new Handler().post(new Runnable() { @Override public void run() { if (scrollHeight != 0){ mScrolView.scrollTo(0, 400); } } }); } }else { mScrolView.scrollTo(0, 0); } } }); // 這個是view的座標獲取方法 private int getViewYLocationInScreeen(View view){ int[] location = new int[2]; view.getLocationInWindow(location); return location[1]; }
這裡的移動的距離150, 300也是大致估算的,有時候佈局也顯得不怎麼好看。但是這裡不能進行計算了在進行移動距離,會出一些問題,現在忘了什麼問題了。
digts 和 inputType 衝突
當digts在xml運用時,如果在程式碼中設定 inputType的話,會使digts失效,具體的原因其他網友有分析過,大致就是會覆蓋之類的,
//顯示密碼:
mPW.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
//隱藏密碼:
mPW.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
用其他的方式去顯示和隱藏密碼:
顯示密碼:
mPW.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
隱藏密碼:
mPW.setTransformationMethod(PasswordTransformationMethod.getInstance());
digts的應用:
digts
在editText 中經常會限制輸入,特別是一些字元相關的,個人認為有InputFilter 、正則表示式、 digts等方式,digts其實 比較好用,先說digts吧,由於digts是採用xml中屬性形式,並且需要一個個打出相應的字元表示可以輸入的;這樣會有些問題:一些特殊字元的輸入,字元需要窮舉出來,比如一些特殊字元在xml中有些限制,一些常規字元是可以直接鍵盤打出來,像 < \ > ? | ; 等等這些常規字元,像 三角符合 △,π,· 這些特殊符合無法直接寫在xml中,需要用相應的ASCII 碼錶示(線上轉換工具),通過這個工具把特殊字元對應的ASCII碼找到,然後加上 "&#" 及末尾的“;” ,如下所示:
< //代表 <
£ //代表 £
<string name="common_password_et_content">0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-/:;()>€[email protected]"'!?,._\|~=+*^%#}{][-×÷π√|`~°&<£¥¢¶©®•</string>
或者可以查詢別人已經列好的ASCII碼對應表 對應表;
InputFilter 應用
android api 中有 LengthFilter ,實現此類要實現 filter 方法,比如實現禁止空字元輸入的filter 程式碼為:
//禁止輸入空格 filter
InputFilter filter = new InputFilter() {
@Override
public CharSequence filter(CharSequence charSequence, int i, int i1, Spanned spanned, int i2, int i3) {
if (charSequence.equals(" "))
return "";
return null;
}
};
mAccountEt.setFilters(new InputFilter[] {filter , new InputFilter.LengthFilter(20)});
這個InputFilter 可以和正則表示式結合使用,比如一些常用的正則表示式,中文字元unicode編碼開始和結束分別對應著 “\u4e00”和“\u9fa5”;
//允許輸入小寫字母、大寫字母、數字、中劃線、下劃線、@符號、空格、中文
public static final String REX_NAME = "[^a-zA-Z0-9\\-\\_\\@\\s\\u4e00-\\u9fa5]";
public static final String REX_PASSWORD = "[^a-zA-Z0-9\\!\\#\\$\\%\\(\\)\\*\\+\\,\\-\\.\\/\\<\\=" + "\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~]*";
後面再專門對正則表示式的應用專門寫一篇部落格,由於這方面的應用場景還是挺多的,而且知識點也不少。