Material Design 之 TextInputLayout和TextInputEditText

依然範特稀西發表於2016-12-30

寫在前面

更多Material Design 文章請看:
Material Design 之 Toolbar 開發實踐總結
Material Design之 AppbarLayout 開發實踐總結
Material Design 之 Behavior的使用和自定義Behavior
Material Design 之 TabLayout 使用
文字框相信大家都很熟悉,文字框可以讓使用者輸入文字。它們可以是單行的,帶或不帶滾動條,也可以是多行的,並且帶有一個圖示。點選文字框後顯示游標,並自動顯示鍵盤。除了輸入,文字框可以進行其他任務操作,如文字選擇(剪下,複製,貼上)以及資料的自動查詢功能。這篇文章講的就是Material Design 風格的文字框,它有有一些比較炫酷的動畫效果(比如輸入的時候,內嵌標籤會浮動到內容的上方),此外還給我一些特別有用的功能,如錯誤提示、計數等等。Material Design 風格的文字框是用TextInputLayout 和TextInputEditText 兩個View來實現的,該類support design 包中。下面就來看一下TextInputLayout 的具體用法。

TextInputLayout 使用

TextInputLayout介紹

首先來看一下TextInputLayout,TextInputLayout 是EditText(或者EditText子類)的一個包裝類,它主要用於在使用者輸入文字的時候顯示一個浮動標籤,也支援顯示錯誤資訊和字元計數等功能。同樣它也支援密碼可見切換按鈕,通過setPasswordVisibilityToggleEnabled(boolean)API 或者 xml 中的屬性,如果設定該屬性為可用(enable),那麼當EditText 顯示設定的密碼時,會顯示一個切換密碼可見和隱藏的按鈕。

注意:當使用密碼切換按鈕的時候,EditText 結束位置的 圖示時會被覆蓋的,為了保證EditText 結束位置Drawable的正常顯示,你需要設定這些Drawables 的相對位置( 相對start的位置/相對結束的位置)。

圖示覆蓋,如下圖:

Material Design 之 TextInputLayout和TextInputEditText
override_drawable.png

如上圖所示,切換密碼可見的按鈕(眼睛圖示)和錯誤提示的圖示 覆蓋在一起了。

TextInputLayout 重要方法和屬性

來看一下TextInputLayout 的一些重要方法和屬性:

  • app:counterEnabled 字元計數是否可用
    程式碼中對應的方法為:setCounterEnabled(boolean)

  • app:counterMaxLength 計數最大的長度
    程式碼中對應的方法為:setCounterMaxLength(int )

  • app:counterOverflowTextAppearance 計數超過最大長度時顯示的文字樣式

  • app:counterTextAppearance 顯示的計數的文字樣式。

  • app:errorEnabled 顯示錯誤資訊是否可用

  • app:errorTextAppearance 顯示錯誤資訊的文字樣式

  • android:hint 浮動標籤
    程式碼對應方法:setHint(CharSequence)

  • app:hintAnimationEnabled 控制是否需要浮動標籤的動畫
    程式碼對應方法:setHintAnimationEnabled(boolean)
  • app:hintEnabled 控制是否顯示浮動標籤
    程式碼對應方法:setHintEnabled(boolean)
  • app:hintTextAppearance 浮動標籤的文字樣式
    程式碼對應方法:setHintTextAppearance(int)
  • app:passwordToggleDrawable 密碼可見切換圖示
    程式碼對應方法:setPasswordVisibilityToggleDrawable(int)或者setPasswordVisibilityToggleDrawable(Drawable)
  • app:passwordToggleEnabled 控制是否顯示密碼可見切換圖示
    程式碼對應方法:setPasswordVisibilityToggleEnabled(boolean)
TextInputLayout 使用示例

瞭解了以上的屬性和方法後,我們看一下具體使用:
1,帶浮動標籤的文字框
程式碼如下:

     />
    <android.support.design.widget.TextInputLayout
        android:id="@+id/text_input_layout_user"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        app:counterOverflowTextAppearance="@style/TextOverCount"
        android:scrollbarAlwaysDrawHorizontalTrack="true"
        android:textColorHint="@color/colorHint"
        >
         <EditText
             android:id="@+id/text_input_user"
             android:layout_width="match_parent"
             android:layout_height="48dp"
             android:hint="使用者名稱"
             android:inputType="text"
             android:textColor="@color/black"
             />

    </android.support.design.widget.TextInputLayout>
    <android.support.design.widget.TextInputLayout
        android:id="@+id/text_input_layout_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        app:counterOverflowTextAppearance="@style/TextOverCount"
        android:scrollbarAlwaysDrawHorizontalTrack="true"
        android:textColorHint="@color/colorHint"
        >
        <EditText
            android:id="@+id/text_input_phone"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:hint="手機號碼"
            android:inputType="number"
            android:textColor="@color/black"
            />

    </android.support.design.widget.TextInputLayout>複製程式碼

效果如下:

Material Design 之 TextInputLayout和TextInputEditText
Floating_label.gif

2,帶字元計數的文字框
佈局:

<android.support.design.widget.TextInputLayout
        android:id="@+id/text_input_layout_user"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:textColorHint="@color/colorHint"
        >
         <EditText
             android:id="@+id/text_input_user"
             android:layout_width="match_parent"
             android:layout_height="48dp"
             android:hint="使用者名稱"
             android:inputType="text"
             android:textColor="@color/black"
             />

    </android.support.design.widget.TextInputLayout>
    <android.support.design.widget.TextInputLayout
        android:id="@+id/text_input_layout_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"

        android:scrollbarAlwaysDrawHorizontalTrack="true"
        android:textColorHint="@color/colorHint"
        >
        <EditText
            android:id="@+id/text_input_phone"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:hint="手機號碼"
            android:inputType="number"
            android:textColor="@color/black"
            />
    </android.support.design.widget.TextInputLayout>複製程式碼

在Activity 中設定,計數的長度:


        mTextInputLayoutUser = (TextInputLayout) findViewById(R.id.text_input_layout_user);
        //設定可以計數
        mTextInputLayoutUser.setCounterEnabled(true);
        //計數的最大值
        mTextInputLayoutUser.setCounterMaxLength(20);複製程式碼

效果如下:

Material Design 之 TextInputLayout和TextInputEditText
count_edittext.gif

如上圖所示,右下角會自動計數,當超過最大值時,計數文字、浮動標籤和下標線都變成了紅色,然後我們也可以用上面介紹的屬性來更改:
新增程式碼

app:counterOverflowTextAppearance="@style/TextOverCount"複製程式碼

style 的程式碼如下:


    <style name="TextOverCount" parent="Base.TextAppearance.AppCompat.Light.Widget.PopupMenu.Small">
      <item name="android:textColor">@android:color/holo_green_light</item>
    </style>複製程式碼

效果如下:

Material Design 之 TextInputLayout和TextInputEditText
count_over_apprence.png

如上圖,將顯示的顏色改為了綠色,當然也可以在style中改字型的大小,在新增一個item 就行

<item name="android:textSize">20sp</item>複製程式碼

更改計數文字的顯示樣式是一樣的,定義一個style ,然後通過app:counterTextAppearance 設定就行。

3,顯示密碼可見和隱藏的切換按鈕
程式碼如下:

 <android.support.design.widget.TextInputLayout
        android:id="@+id/text_input_layout_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:textColorHint="@color/colorHint"
        app:passwordToggleEnabled="true"
        app:passwordToggleTint="@color/colorHint"
        app:passwordToggleDrawable="@drawable/ic_eye_grey_24dp"
        >

        <android.support.design.widget.TextInputEditText
            android:id="@+id/text_input_password"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:hint="密碼"
            android:textColor="@color/black"
            android:inputType="textPassword"
            android:singleLine="true"
            />
    </android.support.design.widget.TextInputLayout>複製程式碼

效果如下:

Material Design 之 TextInputLayout和TextInputEditText
toggle.gif

如上圖,可以看到,右邊多了一個圖示,點選圖示可以使密碼是明文或者隱藏。只是在佈局檔案中新增了幾個屬性

        app:passwordToggleEnabled="true"
        app:passwordToggleTint="@color/colorHint"
        app:passwordToggleDrawable="@drawable/ic_eye_grey_24dp"複製程式碼

當然了,也可依在程式碼中設定,一樣的效果,不在演示。
4, 顯示錯誤資訊
TextInputLayout 是可以顯示錯誤資訊的,這種需求很常見沒,比如登入的時候密碼錯誤,給出相應的提示,比Toast 提示更加友好。
程式碼如下:

        mTextInputLayoutPassword = (TextInputLayout) findViewById(R.id.text_input_layout_password);
        mInputEditTextPassword = (TextInputEditText) findViewById(R.id.text_input_password);

        mInputEditTextPassword.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                mTextInputLayoutPassword.setErrorEnabled(false);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String password = mInputEditTextPassword.getText().toString();
                if(TextUtils.isEmpty(password)||password.length()<6){
                    mTextInputLayoutPassword.setError("密碼錯誤不能少於6個字元");
                }

            }
        });複製程式碼

效果如下:

Material Design 之 TextInputLayout和TextInputEditText
error_tip.gif

當密碼不正確的時候,顯示錯誤提示,當內容發生變幻的時候,記得呼叫

mTextInputLayoutPassword.setErrorEnabled(false);複製程式碼

否則錯誤資訊會一直顯示介面上。

當然有些時候我們不需要浮動標籤,或者不需要浮動標籤的動畫,我們可以控制,將對應屬性設定為false就行了。

TextInputEditText 使用

上面講了TextInputLayout的使用,那麼TextInputEditText是幹什麼的呢? 其實就是一個EditText 的子類,上面講的所有功能,TextInputLayout 裡面包的子View既可以是EditText,也可以是TextInputEditText,效果是一樣的。根據文件的解釋,官網原文:A special sub-class of EditText
designed for use as a child of TextInputLayout。Using this class allows us to display a hint in the IME when in 'extract' mode.

解釋:TextInputEditText 是 EditText 的子類,專門用作TextInputLayout的子View。它允許再`extract`模式(提取模式)下顯示浮動標籤。

也看過一些文章說,橫屏模式EditText 不顯示浮動標籤,TextInputEditText 會顯示浮動標籤,但是我測試了一下,並沒有發現所說的EditText 不顯示浮動標籤,TextInputEditText 會顯示浮動標籤。如果有知道的,請在評論區告知一下。,測試效果如下:(上看兩個是EditText,最後一個是TextInputEditText)

Material Design 之 TextInputLayout和TextInputEditText
text_input_edit.gif

TextInputEditText 、EditText 作為TextInputLayout 的子View使用差別很小,既然Google 說在extract 模式下TextInputEditText 更好,那我們開發中使用TextInputEditText配合TextInputLayout使用就好了。

另外,上面講了TextInputLayout 可以顯示錯誤資訊,TextInputEditText也是可以顯示錯誤資訊的,用下面兩個方法:

mInputEditTextUser.setError("格式不正確");
//或者
mInputEditTextUser.setError("格式不正確",getDrawable(R.drawable.activity_close));複製程式碼

Material Design 之 TextInputLayout和TextInputEditText
error_tip2.png

最後

以上就是TextInputLayout和TextInputEditText 的全部內容,Demo 請戳MaterialDesignSamples。元旦之前來一發,祝大家元旦快樂!!

相關文章