最近在写些小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的焦点监听代码删去就能够了。运行,就能够看到如出一辙的效果了。
文章至此就结束了,可是我要学的东西还有不少,文章里的某些知识出于我我的理解,可能会有不足或者错误,欢迎你们指正!
因为这里的代码比较简单,工程就不上传了,你们动手敲一敲,相信没有问题的。