最近在写些小Demo复习基础,在用到EditText的时候忽然发现以前几乎没有注意到它的光标和下划线的颜色,因而花了很多时间,看了很多博客,如今就来总结和分享一下收获。android
咱们要在原生的EditText上修改,首先固然要认识一下它的原本面目。在Android Studio中新建一个工程,让MainActivity继承于AppCompatActivity(为何要这样作,后面再说),而后在MainActivity的布局中放置一个EditText:面试
<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>
运行工程,仔细观察能够看到光标和下划线都是粉红色的。如今就让咱们按部就班,先修改它的光标颜色。架构
EditText
有一个属性:android:textCursorDrawable
,它就是用来设置光标样式的。为了加深认识,你们先额外作个小实验:将textCursorDrawable
设置为@null
,表示去除系统默认的样式,但咱们都记得隐藏光标的属性是android:cursorVisible
, 那么这时光标会是什么样子的呢?你能够给文字(android:textColor
)和提示文字(android:textColorHint
属性)设置不一样的颜色,运行以后就会发现此时光标的颜色是跟文字的保持一致的。app
了解了android:textCursorDrawable
的做用以后,咱们能够在drawable资源文件夹下新建一个cursor_color.xml
文件,内容以下ide
<?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
:布局
<EditText android:textCursorDrawable="@drawable/cursor_color" android:hint="自定义光标颜色" android:layout_width="match_parent" android:layout_height="wrap_content" />
运行效果以下:学习
第2节中,咱们将属性android:textCursorDrawable
设置为“@null”
以后发现光标的样式会变得跟文字的颜色同样,那么若是将整个EditText
的背景设置为“@null”
呢?咱们能够添加一个EditText,而后为它增长属性android:background="@null"
:spa
能够看到,虽然光标的样式没有改变,可是下划线消失了,不过除此以外,EditText
的边距也没有了,若是不是光标在闪烁,一眼看上去就像个TextView
了。3d
网上有些自定义EditText
下划线的教程就是这样操做的,先把背景去除,再在下面加一个横线。这样的操做何尝不可,可是为了美观,仍是得从新设置间距值。。code
还记得刚才咱们在建立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的焦点监听代码删去就能够了。运行,就能够看到如出一辙的效果了。
文章至此就结束了,可是我要学的东西还有不少,文章里的某些知识出于我我的理解,可能会有不足或者错误,欢迎你们指正!
因为这里的代码比较简单,工程就不上传了,你们动手敲一敲,相信没有问题的。
Android学习PDF+架构视频+面试文档+源码笔记