官术网_书友最值得收藏!

3.4 編輯框

本節介紹Android的兩種編輯框,分別是文本編輯框EditText與自動完成編輯框AutoCompleteTextView。在介紹EditText控件時,除了基本屬性和方法,還另外闡述了常見的4種編輯處理:更換光標、更換邊框、自動隱藏輸入法和輸入回車符自動換行。

3.4.1 文本編輯框EditText

EditText是文本編輯框,用戶可在此輸入文本等信息。EditText的常用屬性說明如下。

●inputType:指定輸入的文本類型,代碼中對應的方法是setInputType。輸入類型的取值說明見表3-3,若同時使用多種文本類型,則可使用豎線“”把多種文本類型拼接起來。

表3-3 輸入類型的取值說明

● maxLength:指定文本允許輸入的最大長度。該屬性無法通過代碼設置。

● hint:指定提示文本的內容,代碼中對應的方法是setHint。

● textColorHint:指定提示文本的顏色,代碼中對應的方法是setHintTextColor。

編輯框除了上述文本與提示文本的基本操作外,實際開發中還常常關注4個方面:更換編輯框的光標、更換編輯框的邊框、自動隱藏輸入法、輸入回車符自動跳轉。

1.更換編輯框的光標

EditText與光標處理有關的屬性主要有兩個,分別是:

● cursorVisible,指定光標是否可見。代碼中對應的方法是setCursorVisible。

● textCursorDrawable,指定光標的圖像。該屬性無法通過代碼設置。

如果要隱藏光標,就要把cursorVisible設置為false。如果要變更光標的樣式,就要修改textCursorDrawable設置新圖像。如圖3-13所示,光標被換成自定義的紅色豎線光標。

圖3-13 給EditText更換圖標樣式

2.更換編輯框的邊框

EditText的邊框通過background屬性控制,如果要隱藏邊框,就要把background設置為@null;如果要修改邊框的樣式,就要將background設置為其他邊框圖形。

下面是一個邊框定義XML的例子,一旦編輯框獲得焦點(例如用戶點擊了該編輯框),邊框就會顯示圖形shape_edit_focus;否則默認顯示shape_edit_normal。

        <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:state_focused="true" android:drawable="@drawable/shape_edit_focus"/>
            <item android:drawable="@drawable/shape_edit_normal"/>
        </selector>

上述自定義邊框的效果如圖3-14所示,未點擊時顯示灰色的圓角邊框,點擊后顯示藍色的圓角邊框。

圖3-14 給EditText更換邊框樣式

3.自動隱藏輸入法

如果頁面上有EditText控件,開發者又沒做其他處理,那么用戶打開該頁面時往往會自動彈出輸入法。這是因為編輯框會默認獲得焦點,即默認模擬用戶的點擊操作,于是輸入法的軟鍵盤就彈出了。要想避免這種情況,就得阻止編輯框默認獲得焦點。比較常見的做法是給該頁面的根節點設置focusable和focusableInTouchMode屬性,通過將這兩個屬性設置為true可強制讓根節點獲得焦點,從而避免輸入法自動彈出的尷尬。

由于軟鍵盤通常會遮蓋“登錄”“確認”“下一步”等按鈕,造成用戶輸入完畢得再點一次返回鍵才能關閉軟鍵盤。大家都希望省事點,比如手機號輸入滿11位軟鍵盤自動關閉,這樣就會極大改善用戶體驗。一個好用的App就是在這一點一滴中體現出來的。

想讓編輯框文本達到指定長度時自動關閉輸入法,開發者需要獲得兩個參數,第一個是該編輯框允許輸入的最大長度,第二個是當前已經輸入的文本長度。當已輸入的文本長度等于最大長度時,即可觸發關閉軟鍵盤。自動隱藏輸入法可分解為3個功能點,分別是獲取編輯框的最大長度、監控當前已輸入的文本長度和關閉軟鍵盤。

(1)獲取編輯框的最大長度

前面我們了解到maxLength屬性可設置最大長度,但是EditText并沒有提供獲取最大長度的方法,不過我們可以通過反射方式曲線獲得最大長度,具體代碼如下:

            public static int getMaxLength(EditText et) {
                int length = 0;
                try {
                    InputFilter[] inputFilters = et.getFilters();
                    for(InputFilter filter :inputFilters){
                        Class<? > c = filter.getClass();
                        if (c.getName().equals("android.text.InputFilter$LengthFilter")) {
                            Field[] f = c.getDeclaredFields();
                            for(Field field :f){
                                if (field.getName().equals("mMax")) {
                                    field.setAccessible(true);
                                    length=(Integer)field.get(filter);
                                }
                            }
                        }
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
                return length;
            }

(2)監控當前已輸入的文本長度

這個監控操作用到一個文本監聽器接口TextWatcher,該接口提供了3個監控方法,具體說明如下。

● beforeTextChanged:在文本改變之前觸發。

● onTextChanged:在文本改變過程中觸發。

● afterTextChanged:在文本改變之后觸發。

這里用到的是afterTextChanged方法,開發者需要自己寫個監聽器實現TextWatcher接口,另外再給EditText對象調用addTextChangedListener方法注冊該監聽器。下面是一個具體實現該監聽器的例子:

            private class HideTextWatcher implements TextWatcher {
                private EditText mView;
                private int mMaxLength;
                private CharSequence mStr;


                public HideTextWatcher(EditText v) {
                    super();
                    mView = v;
                    mMaxLength = ViewUtil.getMaxLength(v);
                }


                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }


                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    mStr = s;
                }


                @Override
                public void afterTextChanged(Editable s) {
                    if (mStr == null || mStr.length() == 0)
                        return;
                    if (mStr.length() == 11 && mMaxLength == 11) {
                        ViewUtil.hideAllInputMethod(EditHideActivity.this);
                    } else if (mStr.length() == 6 && mMaxLength == 6) {
                        ViewUtil.hideOneInputMethod(EditHideActivity.this, mView);
                    }
                }
            }

(3)關閉軟鍵盤

輸入法通過系統服務INPUT_METHOD_SERVICE管理,所以隱藏輸入法也要通過該服務實現。下面是關閉軟鍵盤的兩種方式及其代碼:

① 調用toggleSoftInput方法:

            public static void hideAllInputMethod(Activity act) {
                InputMethodManager imm = (InputMethodManager)
    act.getSystemService(Context.INPUT_METHOD_SERVICE);
                if(imm.isActive()==true){  //軟鍵盤如果已經打開就要關閉
                    imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
                }
            }

② 調用hideSoftInputFromWindow方法:

            public static void hideOneInputMethod(Activity act, View v) {
                InputMethodManager imm = (InputMethodManager)
    act.getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }

完成隱藏輸入法的編碼后,可在頁面上觀察效果,如圖3-15所示。此時手機號碼輸入了10位,還沒達到11位的最大長度,故而輸入法依然顯示。手機號再輸入一位數字,總長度11位達到最大長度的限制,于是輸入法自動隱藏,如圖3-16所示。

圖3-15 輸入10位手機號碼

圖3-16 輸入11位手機號碼

4.輸入回車符自動跳轉

在錄入用戶信息時(比如輸入姓名、密碼等),往EditText控件輸入回車鍵,常常不是換行而是讓光標直接跳到下一個編輯框。該功能用到了文本監聽器接口TextWatcher,主要監聽用戶是否輸入回車符,如果監控到已輸入回車符,就自動將焦點移到下一個控件,從而實現回車符自動跳轉的要求。

下面是回車符監聽器的代碼,注意注釋部分的文字說明:

              private class JumpTextWatcher implements TextWatcher{
                    private EditText mThisView=null;
                    private View mNextView=null;


                    public JumpTextWatcher(EditText vThis, View vNext){
                       super();
                       mThisView=vThis;
                       if(vNext! =null){
                        mNextView=vNext;
                   }
                }


                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after){
                }


                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count){
                }


                @Override
                public void afterTextChanged(Editable s){
                        String str=s.toString();
                        if(str.indexOf("\r")>=0||str.indexOf("\n")>=0){  //發現輸入回車符或換行符
                        mThisView.setText(str.replace("\r", "").replace("\n", ""));  //去掉回車符和換行符
                        if (mNextView ! = null) {
                            mNextView.requestFocus();  //讓下一個視圖獲得焦點,即將光標移到下個視圖
                            if (mNextView instanceof EditText) {
                                EditText et = (EditText)mNextView;
                                //讓光標自動移到編輯框內部的文本末尾
                                //方式一 :直接調用EditText的setSelection方法
                                et.setSelection(et.getText().length());
                                //方式二 :調用Selection類的setSelection方法
                                //Editable edit = et.getText();
                                //Selection.setSelection(edit, edit.length());
                            }
                        }
                    }
                }
            }

下面演示一下輸入回車符自動跳轉的效果圖,文本輸入完畢后還沒輸入回車符,此時焦點仍然停留在編輯框,如圖3-17所示。輸入回車符,此時焦點離開編輯框,并自動移動到“登錄”按鈕(編輯框的光標消失,按鈕背景變深),如圖3-18所示。

圖3-17 未按回車符

圖3-18 已按回車符

3.4.2 自動完成編輯框AutoCompleteTextView

自動完成編輯框一般用于搜索文本框,如在電商App的搜索框輸入商品文字時,下方會自動彈出提示詞列表,方便用戶快速選擇具體商品。AutoCompleteTextView的實現原理是:EditText結合監聽器TextWatcher與下拉列表Spinner,一旦監控到EditText的文本發生變化,就自動彈出適配好的文字下拉列表,選中具體的下拉項向EditText填入相應文字。

AutoCompleteTextView新增的幾個屬性都與下拉列表有關,詳細說明見表3-4。

表3-4 自動完成編輯框的屬性和設置方法說明

下面是使用AutoCompleteTextView的代碼:

                String[] hintArray = {"第一", "第一次", "第一次寫代碼", "第一次領工資", "第二", "第二個"};
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                        this, R.layout.item_dropdown, hintArray);
                AutoCompleteTextView ac_text= (AutoCompleteTextView) findViewById(R.id.ac_text);
                ac_text.setAdapter(adapter);

自動完成編輯框的具體效果如圖3-19所示,下拉列表的內容會自動與編輯框的文本進行匹配。

圖3-19 自動完成編輯框的自動匹配下拉列表

主站蜘蛛池模板: 内江市| 房山区| 河间市| 靖西县| 额敏县| 鲜城| 三都| 达尔| 邮箱| 新巴尔虎左旗| 钟山县| 华安县| 博野县| 日照市| 兰溪市| 海晏县| 泽州县| 临沧市| 浦东新区| 德江县| 策勒县| 玉环县| 无棣县| 武安市| 渭源县| 金坛市| 卢龙县| 甘谷县| 松阳县| 临城县| 泽普县| 崇州市| 安溪县| 九寨沟县| 兴国县| 兴海县| 岚皋县| 乌鲁木齐市| 宝应县| 蒙城县| 九龙县|