從登陸介面學習TextInputLayout

Code4Android發表於2019-03-04

前言

原始碼傳送門

在 Material Design出現之前,如果我們想寫一個登陸介面是不是一般都寫兩組TextView,EditText及一個Button,如果你想在賬號和密碼後面加一個計數的功能,又需要加控制元件並且要自己實現計數,或者在密碼框後面加個類似眼睛的密碼顯示開關,或者你想加一個賬號或者密碼輸入無效或者錯誤的提醒,一般是顯示一個Toast或者使用EditText的setError設定,不過體驗並不是太好,等等這些麻煩的的處理在Material Design TextInputLayout出現後得到了極大改善,我們可以做最少的事達到最好的效果,今天的這篇文章就是通過一個登陸介面來學習TextInputLayout的API重要方法及其使用。先來一張效果圖

從登陸介面學習TextInputLayout
這裡寫圖片描述

新增依賴

TextInputLayout是在Material Design中的,所以我們需要在gradle 檔案配置

dependencies {
    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.android.support:design:24.2.0'
}複製程式碼

使用

TextInputLayout官方文件API中描述它是一種新的繼承自LinearLayout的佈局,使用時只能包含一個EditText或其子類的控制元件,該佈局可以通過設定hint和Error顯示浮動標籤。接下我們看看佈局檔案

          <LinearLayout
            android:id="@+id/account_login_form"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <android.support.design.widget.TextInputLayout
                android:id="@+id/accountinput"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/prompt_account"
                >

            <EditText
                android:id="@+id/account"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:inputType="phone"
                android:singleLine="true"/>

            </android.support.design.widget.TextInputLayout>
            <android.support.design.widget.TextInputLayout
                android:id="@+id/passwordinput"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/prompt_password"
                >

            <EditText
                android:id="@+id/password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:singleLine="true"/>

            </android.support.design.widget.TextInputLayout>

            <Button
                android:id="@+id/account_sign_in_button"
                style="?android:textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:background="@drawable/login_btn"
                android:textColor="@color/btninvalid"
                android:text="@string/action_sign_in"
                android:textStyle="bold"/>

        </LinearLayout>複製程式碼

使用其實很簡單,只需要一個TextInputLayout(需要全路徑)容器並在其中加一個EditText(或子類),需要注意的是一個TextInputLayout有且只能對應一個EditText。在TextInputLayout加入android:hint="賬號"就可以顯示一個浮動標籤了,效果圖如上,還可以通過下面程式碼將浮動標籤關閉,如果關閉的話,設定hint也就沒有效果了,預設是開啟的。

app:hintEnabled="false"複製程式碼

對於android:hint="賬號"屬性在TextInputLayout或者在EditText中設定都可以達到我們浮動標籤的效果,但是不能在兩者中同時使用設定hint,當兩者同時使用時沒有獲取焦點時都會顯示hint(兩個hint重疊顯示),獲取焦點時TextInputLayout設定的hint會成為懸浮標籤,但是此時EditText設定的hint不會消失,有輸入內容時才會消失,具體原因可以自己閱讀原始碼檢視,程式碼不多,很容易看出來。對於浮動標籤顯示隱藏切換有一個過渡動畫,可以通過 app:hintAnimationEnabled="boolean"設定。

如果我們此時想在賬號那一欄後面加個字數統計,例如一般情況我們的賬號是固定位數的,如果使用手機號作為我們的登入賬號,此時我們加一個統計輸入長度可以提示使用者當然也可以超過位數時限制其輸入,我們只需要在TextInputLayout加入

app:counterEnabled="true"複製程式碼

預設是關閉的,當然我們可以設定一個輸入的最大長度,此處設定11.

app:counterMaxLength="11"複製程式碼

當我們設定輸入的最大技術長度11時並不是到達11後不能再輸入計數,而是會以一種顏色提示使用者強調超過設定長度。

TextInputLayout提供了設定錯誤提醒的功能,在此篇文章中我們用手機號及密碼至少6位做判斷,

   if (TextUtils.isEmpty(account)||!isAccountValid(account)) {
            accountinput.setError(getString(R.string.error_invalid_account));
       }

   if (TextUtils.isEmpty(password)||!isPasswordValid(password)) {
            passwordinput.setError(getString(R.string.error_invalid_password));
        }
   private boolean isAccountValid(String name) {
        //TODO: Replace this with your own logic
        Pattern pattern= Pattern.compile("^(13[0-9]|14[5|7]|15\\d|17[6|7]|18[\\d])\\d{8}$");
        return pattern.matcher(name).matches();
        }

    private boolean isPasswordValid(String password) {
        //TODO: Replace this with your own logic
        return password.length() > 6;
    }複製程式碼

當我們輸入不符合規則,設定錯誤,顯示效果如下,

從登陸介面學習TextInputLayout
這裡寫圖片描述

對於設定錯誤,可以通過app:errorEnabled="boolean"或者程式碼accountinput.setEnabled(boolean);將其開啟或者關閉,當通過accountinput.setError()設定錯誤時原始碼中預設呼叫setEnabled(true)開啟,無需自己再次呼叫,還有一個注意的地方設定後不會自動取消,需要自己呼叫accountinput.setError(null);取消錯誤提示。例如在上面圖示提示錯誤後,我們在編輯該EditText時需要取消錯誤提示,那麼我們可以通過addTextChangedListener監聽,程式碼如下

 mAccountView.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) {
            }
            @Override
            public void afterTextChanged(Editable s) {
                if(accountinput.getError()!=null){
                    accountinput.setError(null);
                }
            }
        });複製程式碼

當我們編輯時回撥執行,我們通過getError獲取設定的錯誤資訊,如果設定的有內容則返回設定的字元,預設為null。

對於輸入密碼的空間我們通過TextInputLayout中EditText 的android:inputType="textPassword"設定輸入密碼,此時我們可以在右側看到一個眼睛的密碼開關實現將密碼顯示或隱藏。如果我們不想顯示這個眼睛圖示可以在TextInputLayout中加入

app:passwordToggleEnabled="false"複製程式碼

此時就看不到眼睛的圖示,密碼也不在隱藏,當我們想將眼睛的圖示設定為我們自己設計的圖示時,可以通過下面程式碼設定

app:passwordToggleDrawable="@drawable/common_full_open_on_phone"複製程式碼

我們還可以通過passwordToggleTint給圖示設定著色並且通過passwordToggleTintMode設定對應模式,達到更好看的效果。
是不是很簡單,這些功能要在之前佈局肯定需要一大堆程式碼的,而現在很簡單,只要幾行程式碼。

自定義EditText下劃線樣式

從登陸介面學習TextInputLayout
這裡寫圖片描述

預設情況下EditText的下劃線是灰色的,當獲取焦點時顏色是colorAccent,如上圖,如果我們想自定義,可以給TextInputLayout加一個theme,如下程式碼

android:theme="@style/customLineColor"複製程式碼

customLineColor樣式為colorControlNormal為沒有獲取焦點時的顏色,colorControlActivated為獲取焦點時的顏色,這樣就可以設定我們想要的顏色了。

    <style name="customLineColor" parent="Theme.AppCompat.Light">
    <item name="colorControlNormal">@color/colorAccent</item>
     <item name="colorControlActivated">@color/drawerTextColor</item>
    </style>複製程式碼

自定義浮動標籤

預設情況下浮動標籤的顏色也是colorAccent,我們可以通過hintTextAppearance設定浮動標籤字型樣式,如
app:hintTextAppearance="@style/hintAppearance",

    <style name="hintAppearance" parent="TextAppearance.AppCompat">
        <item name="android:textSize">14sp</item>
        <item name="android:textColor">@color/colorPrimary</item>
    </style>複製程式碼

自定義錯誤提示資訊

app:errorTextAppearance="@style/errorAppearance"

    <style name="errorAppearance" parent="TextAppearance.AppCompat">
        <item name="android:textSize">14sp</item>
        <item name="android:textColor">@color/red</item>
    </style>複製程式碼

自定義超出計數最大長度樣式

app:counterOverflowTextAppearance="@style/counterOverflowTextAppearance"

    <style name="counterOverflowTextAppearance" parent="TextAppearance.AppCompat">
        <item name="android:textSize">14sp</item>
        <item name="android:textColor">@color/red</item>
    </style>複製程式碼

監控虛擬鍵盤

通過上面的介紹,我們將TextInputLayout的使用及常用的設定都已經都介紹了,既然文章名字是登入介面,下面簡單介紹一下其他一些比較多登入介面的一些實現。如當焦點在賬戶上,我們輸入完成後直接點選虛擬鍵盤上的下一項時焦點直接跳到密碼項,密碼輸入完成,直接可以點選虛擬鍵盤的確定就可以登入,該怎麼實現呢。如下
在賬號的EditText中加入

                android:imeActionId="@+id/password"
                android:imeOptions="actionNext"複製程式碼

在密碼的EditText中加入

                android:imeActionId="@+id/account_sign_in_button"
                android:imeOptions="actionDone"複製程式碼
  mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
                if ( id == EditorInfo.IME_ACTION_DONE) {
                    InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                    //inputMethodManager.showSoftInput(getWindow().getDecorView(),InputMethodManager.SHOW_FORCED);//顯示
                    inputMethodManager.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(),InputMethodManager.RESULT_UNCHANGED_SHOWN);
                    //attemptLogin();
                    startLogin();
                    return true;
                }
                return false;
            }
        });複製程式碼

動態監測登入按鈕

在支付寶中,當賬戶名或者密碼有沒填的項,登入按鈕就是不可點選的,並通過樣式給使用者反饋是不是可以點選。這個也很簡單,只需要給兩個EditText設定addTextChangedListener監聽,監聽兩個控制元件只有有沒填項就將登入按鈕設定為不可以點選,否則可以點選,核心程式碼

   if (account.equals("")||password.equals("")){
                    mAccountSignInButton.setClickable(false);
                    mAccountSignInButton.setTextColor(getResources().getColor(R.color.btninvalid));
                }else{
                    mAccountSignInButton.setClickable(true);
                    mAccountSignInButton.setTextColor(getResources().getColor(R.color.white));
                }複製程式碼

#多賬號自動提示
AutoCompleteTextView是EditText的子類,可以實現自動提示功能該控制元件有一個setAdapter方法,可以監測我們輸入的內容在傳入的介面卡中有資料時會自動彈出下拉提示,在文章開始效果圖已經展示,程式碼簡單實現

    private  String[] accounts = { "18236593333", "13463373657", "18235784765", "18234637686" };

        ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,accounts);
        mAccountView.setAdapter(arrayAdapter);//輸入至少兩個字元才會提示複製程式碼

Ok,到這裡本篇文章就結束了,有問題歡迎留言指出,Have a wonderful day .

相關文章