1. 程式人生 > >EditText 的那些事兒(一)

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碼找到,然後加上  "&#" 及末尾的“;” ,如下所示:

&#060; //代表 < 
&#163; //代表 £
<string name="common_password_et_content">0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-/:;()>€[email protected]"'!?,._\|~=+*^%#}{][-×÷π√|`~°&amp;&#060;&#163;&#165;&#162;&#182;&#169;&#174;&#149;</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\\!\\#\\$\\%\\(\\)\\*\\+\\,\\-\\.\\/\\<\\=" +  "\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~]*";

後面再專門對正則表示式的應用專門寫一篇部落格,由於這方面的應用場景還是挺多的,而且知識點也不少。