最近在寫些小Demo複習基礎,在用到EditText的時候忽然發現以前幾乎沒有注意到它的光標和下劃線的顏色,因而花了很多時間,看了很多博客,如今就來總結和分享一下收穫。android
咱們要在原生的EditText上修改,首先固然要認識一下它的原本面目。在Android Studio中新建一個工程,讓MainActivity繼承於AppCompatActivity(爲何要這樣作,後面再說),而後在MainActivity的佈局中放置一個EditText:app
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.lindroid.edittext.MainActivity"> <EditText android:hint="原生的EditText" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
運行工程,仔細觀察能夠看到光標和下劃線都是粉紅色的。如今就讓咱們按部就班,先修改它的光標顏色。
ide
EditText 有一個屬性:android:textCursorDrawable
,它就是用來設置光標樣式的。爲了加深認識,你們先額外作個小實驗:將textCursorDrawable設置爲@null,表示去除系統默認的樣式,但咱們都記得隱藏光標的屬性是android:cursorVisible
, 那麼這時光標會是什麼樣子的呢?你能夠給文字(android:textColor)和提示文字(android:textColorHint屬性)設置不一樣的顏色,運行以後就會發現此時光標的顏色是跟文字的保持一致的。佈局
瞭解了android:textCursorDrawable
的做用以後,咱們能夠在drawable資源文件夾下新建一個cursor_color.xml文件,內容以下spa
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:width="2dp" /> <solid android:color="@android:color/holo_blue_light" /> </shape>
光標的顏色爲系統自帶的淺藍色,寬度爲2dp。在原生的EditText下面放置一個新的EditText:.net
<EditText android:textCursorDrawable="@drawable/cursor_color" android:hint="自定義光標顏色" android:layout_width="match_parent" android:layout_height="wrap_content" />
運行效果以下:
3d
第2節中,咱們將屬性android:textCursorDrawable
設置爲「@null」以後發現光標的樣式會變得跟文字的顏色同樣,那麼若是將整個EditText的背景設置爲「@null」呢?咱們能夠添加一個EditText,而後爲它增長屬性android:background="@null"
:code
能夠看到,雖然光標的樣式沒有改變,可是下劃線消失了,不過除此以外,EditText的邊距也沒有了,若是不是光標在閃爍,一眼看上去就像個TextView了。orm
網上有些自定義EditText下劃線的教程就是這樣操做的,先把背景去除,再在下面加一個橫線。這樣的操做何嘗不可,可是爲了美觀,仍是得從新設置間距值。。xml
還記得剛纔咱們在建立MainActivity時要繼承AppCompatActivity嗎?到了這裏就要揭曉答案了。這樣作是爲了使用appcompat-v7包中的Material Design樣式,好比咱們能夠在Styles.xml文件中新建一個MyEditText樣式:
<style name="MyEditText" parent="Theme.AppCompat.Light"> <item name="colorControlNormal">@android:color/darker_gray</item> <item name="colorControlActivated">@android:color/holo_orange_dark</item> </style>
colorControlNormal
表示控件默認的顏色,colorControlActivated
表示控件被激活時的顏色,這樣,咱們就能夠分別設置EditText不被選中和選中時的顏色了。這裏我將選中的顏色設爲橙色。
在activity_main.xml中再增長一個EditText,加上android:theme="@style/MyEditText"
屬性,效果以下:
能夠看到,光標和下劃線的顏色都會修改掉,而間距仍是會保留。
前面的作法都是針對一個EditText來修改的,若是須要把項目中全部的EditText的顏色都改掉的話,那這樣作的話工做量就太大了。有沒有辦法能夠一腳定江山的呢?
不知道你發現了沒有,爲何EditText默認是騷氣的粉紅色呢?事實上,你設置其餘幾種控件(好比ProgressBar、Switch等等),它們的顏色基本上也是騷粉。你只要再看一眼剛纔的styles.xml,裏面的AppTheme的代碼是這樣的:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style>
看到了嗎?裏面的colorAccent就是那個騷粉色了。爲了理解這三種顏色,我特意找了一張圖:
前面咱們作的自定義下劃線操做都是在繼承AppCompatActivity的前提下,若是你改爲Activity,而後在Android5.0如下的手機運行的話,效果是這樣的:
Material Design風格消失了,光標的顏色雖然還能修改,可是下劃線的顏色卻改不了。因此咱們還得另想方法。
EditText是一個輸入框,咱們能夠這樣理解:下劃線無非就是給輸入框的下邊框加一條線。這個用Android中的layer-list(圖層)就能夠作到。新建兩個xml文件:et_underline_unselected.xml和et_underline_selected.xml,前者是EditText被選中時的背景,後者則是未被選中時的背景:
et_underline_unselected.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:bottom="0dp" android:left="-2dp" android:right="-2dp" android:top="-2dp"> <shape> <solid android:color="@android:color/transparent" /> <stroke android:width="1dp" android:color="@android:color/darker_gray" /> <padding android:bottom="4dp" /> </shape> </item> </layer-list>
et_underline_selected.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:bottom="0dp" android:left="-2dp" android:right="-2dp" android:top="-2dp"> <shape> <solid android:color="@android:color/transparent" /> <stroke android:color="@android:color/holo_green_light" android:width="2dp" /> <padding android:bottom="4dp" /> </shape> </item> </layer-list>
我將layer-list理解成一個圖層列表,shape就是列表中的一個item,因爲咱們只須要下邊框有橫線,因此除了shape在列表中的下邊距外都設爲負值。光標和下劃線之間要有點距離,因此shape的下方內邊距設爲4dp。固然,被選中時的下劃線寬度要大一點。
在項目中新建一個SecondActivity,繼承於Activity,而後在佈局文件中放置兩個EditText,background都設爲「@null」,光標就用咱們以前的淺藍色。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.lindroid.edittext.SecondActivity"> <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="3dp" android:background="@null" android:hint="自定義EditText下劃線1" android:textCursorDrawable="@drawable/cursor_color" /> <EditText android:id="@+id/editText2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="3dp" android:background="@null" android:hint="自定義EditText下劃線2" android:textCursorDrawable="@drawable/cursor_color" /> </LinearLayout>
而後在代碼中設置EditText的監聽事件
/**初始化EditText,默認都爲未選中狀態**/ editText1.setBackgroundResource(R.drawable.et_underline_unselected); editText2.setBackgroundResource(R.drawable.et_underline_unselected); /**第一個EditText的焦點監聽事件**/ editText1.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { Log.e(TAG, "EditText1得到焦點"); editText1.setBackgroundResource(R.drawable.et_underline_selected); } else { Log.e(TAG, "EditText1失去焦點"); editText1.setBackgroundResource(R.drawable.et_underline_unselected); } } }); /**第二個EditText的焦點監聽事件**/ editText2.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { Log.e(TAG, "EditText2得到焦點"); editText2.setBackgroundResource(R.drawable.et_underline_selected); } else { Log.e(TAG, "EditText2失去焦點"); editText2.setBackgroundResource(R.drawable.et_underline_unselected); } } });
注意,要先將全部的EditText都設置爲運行一下,效果以下:
效果咱們是實現了,可是這樣一來Activity中的代碼顯得太冗長,所以咱們能夠將選中和未選中的狀態封裝到狀態選擇器中。在drawable文件夾下新建一個et_underline_selector.xml文件:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="false" android:drawable="@drawable/et_underline_unselected"/> <item android:state_focused="true" android:drawable="@drawable/et_underline_selected"/> </selector>
android:state_focused
表示控件是否得到焦點。而後在佈局文件中設置 android:background="@drawable/et_underline_selector"
,Activity的焦點監聽代碼刪去就能夠了。運行,就能夠看到如出一轍的效果了。
文章至此就結束了,可是我要學的東西還有不少,文章裏的某些知識出於我我的理解,可能會有不足或者錯誤,歡迎你們指正!
因爲這裏的代碼比較簡單,工程就不上傳了,你們動手敲一敲,相信沒有問題的。