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-/:;()>€$@"'!?,._\|~=+*^%#}{][-×÷π√|`~°&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\\!\\#\\$\\%\\(\\)\\*\\+\\,\\-\\.\\/\\<\\=" +  "\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~]*";

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章