Android Design Support Library使用詳解——TextInputLayout與TextInputEditText

TextInputLayout

在谷歌的Material Design中,文本輸入是這樣表現的:當用戶點擊輸入框想要輸入文字時,若是輸入框是空的,那麼它的提示文字(hint)就會變小而且同時移動到輸入框的上方;若是文字不爲空,則上方一直浮着這個提示文字(見https://material.google.com/components/text-fields.html#text-fields-input )。而且在I/O大會的視頻上,咱們能夠看到整個的動畫過程很優美流暢。在design support library中,TextInputLayout就是提供了它的實現。css

使用

經過TextInputLayout來實現上述這種效果很簡單,就是在佈局代碼中每個EditText外面再套上一個TextInputLayout就能夠了,代碼以下。注意一個TextInputLayout只能套一個EditText,不然會拋異常。html

<android.support.design.widget.TextInputLayout  android:id="@+id/mobile_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/image_title">
    <EditText  android:id="@+id/mobile" style="@style/InputEditText.Login" android:drawableLeft="@drawable/icon_small_phone" android:hint="@string/hint_mobile" android:inputType="number" android:maxLength="11"/>
</android.support.design.widget.TextInputLayout>

編譯運行,效果出現。
這裏寫圖片描述java

顯示錯誤消息

除了顯示提示文字,TextInputLayout還提供了顯示錯誤消息的接口。顯示的方法也很簡單,之前咱們是經過TextView的setError(String)來顯示,如今改成調用TextInputLayout的setError(String)就能夠了。代碼以下:android

ViewParent parent = editText.getParent();
    if (parent instanceof TextInputLayout) {
        ((TextInputLayout)parent).setError(message);
    }
    editText.setError(message);

錯誤消息會直接顯示在編輯框下面,而且不像EditText那樣必需要得到焦點才能顯示出來。如圖所示:
這裏寫圖片描述markdown

除了顯示錯誤消息以外,咱們還須要清空錯誤消息,畢竟不能在用戶改正以後還一直顯示它吧。清空錯誤消息很簡單,只須要調用它的API inputLayout.setErrorEnabled(false);便可。好比咱們能夠在用戶修改EditText時調用它:app

ViewParent viewParent = inputText.getParent();
    if (viewParent != null && viewParent instanceof TextInputLayout) {
        final TextInputLayout inputLayout = (TextInputLayout) viewParent;
        inputText.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                inputLayout.setErrorEnabled(false);
            }
        });
    }

統計輸入字數

TextInputLayout還封裝了輸入框的輸入字數的統計。這一特性在一些字數受限的功能中但是大有用處,好比發個微博提交個用戶反饋,一般都會限定一個最大字數,於是須要顯示給用戶已經輸入了多少個字。
統計字數默認是不開啓的,咱們能夠在屬性裏配置:ide

<android.support.design.widget.TextInputLayout  android:id="@+id/password_layout" app:counterEnabled="true" app:counterTextAppearance="@style/counter" app:counterMaxLength="8" app:counterOverflowTextAppearance="@style/counterOverflow" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/mobile_layout" android:layout_marginBottom="@dimen/margin_double">

counterOverflow定義:佈局

<style name="counterOverflow"> <item name="android:textColor">@color/red</item> </style>

咱們能夠只配置counterEnabled,這樣的話它就只會顯示輸入的字數。而counterTextAppearance屬性則用於配置計數文本外觀。counterMaxLength用於配置最大字數,當配置了它時,就必須再配置counterOverflowTextAppearance,不然當用戶輸入的字數超過這個最大字數時會引起異常。
下圖是咱們配置後的運行效果:
這裏寫圖片描述動畫

其餘屬性與方法請參數API文檔,這裏再也不贅述。google

TextInputEditText

在上一節中,咱們能夠看到TextInputLayout與EditText在搭配使用當中,對於所需的功能都處理得很是好,那麼,爲何還要有TextInputEditText呢?
緣由很簡單,TextInputEditText是爲了填坑的。
當咱們的界面處於橫屏時,點擊一個EditText,默認狀況下不是在它下面彈出鍵盤,而是進入到輸入法的一個全屏的輸入界面(經過配置android:imeOptions="flagNoExtractUi"能夠設爲直接在當前界面顯示)。
通常在咱們要彈出輸入法時,它會與對應的View創建一個鏈接,用於二者之間的互動,好比獲取輸入提示hint,而後在剛纔所述的狀況中顯示到輸入法的輸入界面上。可是當咱們爲EditText外面套上一個TextInputLayout時,TextInputLayout會拿到EditText的hint顯示出來並把EditText自己的hint設爲空。這樣若是跳到輸入法的輸入界面上,就顯示不了咱們所設置的提示文本了。因此TextInputEditText重寫了EditText的onCreateInputConnection(EditorInfo outAttrs)方法,把父容器的hint內容傳給EditorInfo,下面就是它惟一作的事情:

@Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        final InputConnection ic = super.onCreateInputConnection(outAttrs);
        if (ic != null && outAttrs.hintText == null) {
            // If we don't have a hint and our parent is a TextInputLayout, use it's hint for the
            // EditorInfo. This allows us to display a hint in 'extract mode'.
            final ViewParent parent = getParent();
            if (parent instanceof TextInputLayout) {
                outAttrs.hintText = ((TextInputLayout) parent).getHint();
            }
        }
        return ic;
    }

因此當咱們使用了TextInputLayout時,就須要把咱們的EditText換成TextInputEditText。
下面兩張圖分別是使用EditText及TextInputEditText的運行效果:
使用EditText,沒有提示文本
使用TextInputEditText有提示文本

相關文章
相關標籤/搜索