MaterialDesign——TextInputLayout

目前代碼已經(jīng)上傳到GitHub,里面有博客里面Material Design系列的所有代碼
GitHub Material Design

1速梗、什么是TextInputLayout籍茧?

TextInputLayout是22.2.0新添加的控件版述, 要和EditText(或EditText的子類)結(jié)合使用,并且只能包含一個(gè)EditText(或EditText的子類)寞冯,這一點(diǎn)尤其重要院水,在做用戶注冊(cè)的時(shí)候遇到了TextInputLayout里面有獲取驗(yàn)證碼的按鈕,布局的時(shí)候出現(xiàn)問(wèn)題了简十,具體的解決方法詳見(jiàn)下文,TextInputLayout的繼承關(guān)系如下圖所示撬腾。


image.png

2螟蝙、為什么要用TextInputLayout?

遵循Material Design的設(shè)計(jì)民傻,很多APP在用戶登錄胰默、注冊(cè)的頁(yè)面中都使用了TextInputLayout的控件,在一些iOS的APP中也能發(fā)現(xiàn)這種想過(guò)漓踢,通過(guò)一些細(xì)微的動(dòng)畫(huà)效果以及改變顏色牵署,能達(dá)到很炫酷的效果,相比傳統(tǒng)的EditText喧半,在用戶輸入信息的時(shí)奴迅,hint(提示)會(huì)自動(dòng)上移,并且輸入框的下劃線會(huì)高亮挺据,并能夠把輸入校驗(yàn)的錯(cuò)誤能夠在控件下面展示取具,不用Toast彈出提示,并且自帶設(shè)置密碼框的顯示與隱藏扁耐,效果如下圖所示暇检。


TextinputLogin.gif

3、如何使用TextInputLayout婉称?

3.1 首先在build.gradle 引入design的庫(kù)

 implementation 'com.android.support:appcompat-v7:26.1.0'
 implementation 'com.android.support:design:26.1.0'

3.2 其次在xml文件中添加一下代碼

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white">

    <LinearLayout
        android:layout_marginTop="40dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <include layout="@layout/custom_toolbar"/>


        <android.support.design.widget.TextInputLayout
            android:id="@+id/text_input_layout_phone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:scrollbarAlwaysDrawHorizontalTrack="true"
            android:textColorHint="@color/colorHint"
            app:counterOverflowTextAppearance="@style/TextOverCount"
            app:errorTextAppearance="@style/text_input_login_error_style">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/et_phone"
                style="@style/et_login_text"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:layout_centerVertical="true"
                android:hint="@string/phone_hint"
                android:inputType="number"
                android:maxLength="11"
                android:textColor="@color/black"
                android:textColorHint="@color/font_dark_color"
                android:textSize="@dimen/font_middle_size" />

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


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

            <android.support.design.widget.TextInputEditText
                android:id="@+id/et_pwd"
                style="@style/et_login_text"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:hint="@string/pwd_hint"
                android:inputType="textPassword"
                android:maxLength="16"
                android:singleLine="true"
                android:textColor="@color/black"
                android:textSize="@dimen/font_middle_size" />
        </android.support.design.widget.TextInputLayout>


        <Button
            android:id="@+id/btn_login"
            android:layout_width="match_parent"
            android:layout_height="38dp"
            android:layout_marginLeft="80dp"
            android:layout_marginRight="80dp"
            android:layout_marginTop="60dp"
            android:layout_weight="1"
            android:background="@drawable/btn_login_bg_gradient"
            android:text="登錄"
            android:textColor="@color/white"
            android:textSize="@dimen/font_small_size" />


    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="18dp">

        <View
            android:id="@+id/view_center"
            android:layout_width="0.5dp"
            android:layout_height="16dp"
            android:layout_centerInParent="true"
            android:background="@color/line_default_color" />

        <TextView
            android:id="@+id/tv_modify_pwd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="8dp"
            android:layout_toLeftOf="@id/view_center"
            android:text="忘記密碼?"
            android:textColor="#ff5c5f5f"
            android:textSize="12dp" />

        <TextView
            android:id="@+id/tv_phone_register"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:layout_toRightOf="@id/view_center"
            android:text="注冊(cè)"
            android:textColor="#ff5c5f5f"
            android:textSize="12dp" />
    </RelativeLayout>

</RelativeLayout>

3.3在activity中的設(shè)置

package com.codingsnail.materialdesigndemo.view

import CommonUtils
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.text.Editable
import android.text.TextWatcher
import android.widget.Toast
import com.codingsnail.materialdesigndemo.R
import kotlinx.android.synthetic.main.activity_text_input_login.*
import org.jetbrains.anko.sdk25.coroutines.onClick

/**
 * Created by Snail on 3/1/2018 11:31 AM
 * Contact with slowsnail0223@gmail.com
 */
class TextInputLoginActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_text_input_login)
        initView()
    }

    private fun initView() {

         et_phone.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                text_input_layout_phone.isErrorEnabled = false
            }

            override fun afterTextChanged(s: Editable) {

            }
        })
        et_pwd.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                text_input_layout_pwd.isErrorEnabled = false
            }

            override fun afterTextChanged(s: Editable) {
            }
        })

        btn_login.onClick {
            invalidLogin()
        }
    }


    private fun invalidLogin() {


        if (!CommonUtils.verifyMobile(et_phone!!.text.toString().trim())) {
            text_input_layout_phone.error = getString(R.string.error_field_phone)
            return
        }
        if (!CommonUtils.verifyLoginPwd(et_pwd!!.text.toString().trim())) {
            text_input_layout_pwd.error = getString(R.string.error_incorrect_password)
            return
        }
        Toast.makeText(this, "登錄成功", Toast.LENGTH_SHORT).show()
    }

    companion object {

        fun startActivity(context: Context) {
            context.startActivity(Intent(context, TextInputLoginActivity::class.java))
        }
    }
}

這樣就能完成如上git圖所看到的所有功能啦块仆!

4构蹬、TextInputLayout的重要屬性講解

4.1 達(dá)到上面效果我們需要做到的步驟

image.png

XML中配置的如上圖所示,這樣就可以基本完成TextInputLayout的功能了悔据,但是想使用TextInputLayout自帶的錯(cuò)誤提示功能庄敛,在代碼中還需要設(shè)置以下兩點(diǎn)。

4.1.1 需要給TextInputEditText添加 addTextChangedListener監(jiān)聽(tīng)蜜暑,當(dāng)文本有變化的時(shí)候需要?jiǎng)討B(tài)的去設(shè)置铐姚,整個(gè)項(xiàng)目都是用Kotlin寫(xiě)的,Java的寫(xiě)法也是一樣肛捍,只是語(yǔ)法不一樣隐绵。

text_input_layout_pwd.isErrorEnabled = false
image.png

4.1.2 校驗(yàn)錯(cuò)誤的時(shí)候去設(shè)置錯(cuò)誤提示

image.png

可以看到完成1、2點(diǎn)以后就可以使用TextInputLayout的錯(cuò)誤提示功能了

4.2 如何改變默認(rèn)的顏色拙毫,能夠適配自己APP顏色風(fēng)格的UI

image.png

如果我們不進(jìn)行顏色設(shè)置的話依许,那么我們字體的顏色以及下劃線的顏色一定和colorPrimary、colorPrimaryDark缀蹄、colorAccent顏色是一樣的峭跳。

     <!-- 代表 hint 的顏色 -->
        <item name="android:textColorHint">#ff6f7272</item>
        <!-- 代表 下劃線沒(méi)有獲取焦點(diǎn)的顏色 的顏色 -->
        <item name="colorControlNormal">#ffd8d8d8</item>
        <!-- 代表 代表了獲取焦點(diǎn)的時(shí)候 下劃線 的顏色 -->
        <item name="colorControlActivated">#ff3586fe</item>
       <!-- 代表 代表了點(diǎn)擊的時(shí)候 下劃線 的顏色 -->
        <item name="colorControlHighlight">#ff3586fe</item>

然后在我們的AndroidManifest.xml 里面的 application里面運(yùn)用我們?cè)O(shè)置的主題就可以改變顏色了。

4.3 如何改變光標(biāo)的顏色

如果我們不做配置的話缺前,EditText的光標(biāo)的顏色是和系統(tǒng)的colorAccent的顏色一樣的蛀醉,給editText設(shè)置光標(biāo)顏色只需要設(shè)置一個(gè)屬性即可。

 <style name="et_login_text" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:textCursorDrawable">@drawable/cursor_input_et</item>
 </style>

在XML中為這個(gè)editText運(yùn)用這個(gè)style即可

4.4 如何設(shè)置最大數(shù)量限制衅码?

這個(gè)只需要在TextInputLayout里面設(shè)置幾個(gè)屬性就可以了

 <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:counterMaxLength="11"
        app:counterEnabled="true"
        android:scrollbarAlwaysDrawHorizontalTrack="true"
        android:textColorHint="@color/colorHint"
        app:counterOverflowTextAppearance="@style/TextOverCount"
        app:errorTextAppearance="@style/text_input_login_error_style">

counterMaxLength 設(shè)置最大長(zhǎng)度限制
counterEnabled 是否開(kāi)啟超出限制后的提示
counterOverflowTextAppearance 超出限制后hint 的顏色拯刁,以及EditText 下劃線的顏色 16/11 提示文字的顏色以及提示字體的大小都是在這個(gè)里面設(shè)置的


image.png

4.5 密碼功能的小眼睛的顯示與隱藏?

隨著互聯(lián)網(wǎng)的發(fā)展逝段,很多用戶的密碼會(huì)很長(zhǎng)垛玻,很麻煩,在輸入的時(shí)候提示密碼不對(duì)奶躯,這時(shí)候需要?jiǎng)討B(tài)的可以看到密碼的顯示和隱藏密碼帚桩,這種功能在TextInputLayout出來(lái)之前我們都是通過(guò)去標(biāo)記一個(gè)初始狀態(tài),然后點(diǎn)擊圖片的時(shí)候去改變狀態(tài)嘹黔,然后設(shè)置editText的內(nèi)容為可見(jiàn)账嚎,有了TextInputLayout以后,我們只需要去設(shè)置不同狀態(tài)下顯示的圖片就可以了儡蔓,省去了顯示眼睛不同狀態(tài)下圖片的復(fù)雜的業(yè)務(wù)邏輯醉锄,具體的代碼如下:


image.png

login_pwd_eye_selector的代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/close_eyes" android:state_checked="false" />
    <item android:drawable="@mipmap/open_eyes" android:state_checked="true" />
</selector>

下面為密碼開(kāi)關(guān)的一些屬性。
app:passwordToggleEnabled:設(shè)置 password 開(kāi)關(guān)是否可用浙值。
app:passwordToggleTint:設(shè)置 password 開(kāi)關(guān)圖標(biāo)的 tint 著色恳不。
app:passwordToggleTintMode:設(shè)置 password tint 的模式。
app:passwordToggleDrawable:設(shè)置 password 開(kāi)關(guān)圖標(biāo)开呐。
setPasswordVisibilityToggleDrawable:設(shè)置 password 開(kāi)關(guān)圖標(biāo)烟勋。
isPasswordVisibilityToggleEnabled:設(shè)置 password 開(kāi)關(guān)圖標(biāo) 是否可見(jiàn)规求。
setPasswordVisibilityToggleTintList:設(shè)置 password 開(kāi)關(guān)圖標(biāo)的 tint。
setPasswordVisibilityToggleTintMode:設(shè)置 password 開(kāi)關(guān)圖標(biāo)的 tint 模式卵惦。
getPasswordVisibilityToggleDrawable:設(shè)置 password 開(kāi)關(guān)圖標(biāo)阻肿。

4.6 使用過(guò)程中的請(qǐng)求驗(yàn)證碼顯示錯(cuò)位的問(wèn)題

TextinputRegister.gif

在上圖中可以看到TextInputLayout中有一個(gè)獲取驗(yàn)證碼的按鈕,因?yàn)門(mén)extInputLayout里面只能有EditText以及EditText的子類沮尿,所以我們想把獲取驗(yàn)證碼的按鈕放在里面是不可能的丛塌。
最開(kāi)始的時(shí)候的解決方案是TextInputLayout 外面套一層 RelativeLayout,然后把獲取驗(yàn)證碼這個(gè)Button 在RelativeLayout里面居中畜疾,最后發(fā)現(xiàn)這樣寫(xiě)確實(shí)可以赴邻,但是當(dāng)這個(gè)輸入框有錯(cuò)誤提示的時(shí)候,這個(gè)RelativeLayout的高度會(huì)變高啡捶,那么這個(gè)時(shí)候按鈕的位置會(huì)在輸入框的線上姥敛,所以最后把這個(gè)高度居中改為了直接距離上部20dp,這樣問(wèn)題就解決了瞎暑。

總結(jié):TextInputLayout用在登錄彤敛、注冊(cè)頁(yè)面效果還是挺好的,但是就是一個(gè)TextInputLayout占用的高度很高了赌,所以并不適合在很多輸入框的頁(yè)面上墨榄,本文的代碼均是從實(shí)際業(yè)務(wù)中抽離出來(lái)的,可以直接拿去用勿她,代碼詳見(jiàn)文章開(kāi)頭的GitHub地址袄秩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市嫂拴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贮喧,老刑警劉巖筒狠,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異箱沦,居然都是意外死亡辩恼,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)谓形,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)灶伊,“玉大人,你說(shuō)我怎么就攤上這事寒跳∑溉” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵童太,是天一觀的道長(zhǎng)米辐。 經(jīng)常有香客問(wèn)我胸完,道長(zhǎng),這世上最難降的妖魔是什么翘贮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任赊窥,我火速辦了婚禮,結(jié)果婚禮上狸页,老公的妹妹穿的比我還像新娘锨能。我一直安慰自己,他們只是感情好芍耘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布址遇。 她就那樣靜靜地躺著,像睡著了一般齿穗。 火紅的嫁衣襯著肌膚如雪傲隶。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,806評(píng)論 1 290
  • 那天窃页,我揣著相機(jī)與錄音跺株,去河邊找鬼。 笑死脖卖,一個(gè)胖子當(dāng)著我的面吹牛乒省,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播畦木,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼袖扛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了十籍?” 一聲冷哼從身側(cè)響起蛆封,我...
    開(kāi)封第一講書(shū)人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎勾栗,沒(méi)想到半個(gè)月后惨篱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡围俘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年砸讳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片界牡。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡簿寂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宿亡,到底是詐尸還是另有隱情常遂,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布挽荠,位于F島的核電站烈钞,受9級(jí)特大地震影響泊碑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毯欣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一馒过、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酗钞,春花似錦腹忽、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至葫录,卻和暖如春着裹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背米同。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工骇扇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人面粮。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓少孝,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親熬苍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子稍走,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容