继承自 AppCompatActivity
在开发中,我们经常用到 EditText
,一般 EditText 默认样式不能满足我们的需求。下面说下常用的两种修改方法。
android:theme
方式修改- 自定义样式
android:theme
方式修改
<style name="EditTextStyle">
<!--表示控件默认的颜色-->
<item name="android:colorControlNormal">#ccc</item>
<!--表示控件被激活时的颜色-->
<item name="android:colorControlActivated">#ccc</item>
</style>
在 EditText 上加上 android:theme="@style/EditTextStyle"
属性。请记住是 android:theme
而不是 style
。
自定义样式
EditText 有一个属性:android:textCursorDrawable
,它就是用来设置光标样式的。如果将 textCursorDrawable
设置为 @null
,表示去除系统默认的样式,但我们都记得隐藏光标的属性是 android:cursorVisible
, 那么这时光标会是什么样子的呢?这是我们给文字(android:textColor
)和提示文字(android:textColorHint
属性)设置不同的颜色,运行之后就会发现此时光标的颜色是跟文字的保持一致的。
设置光标的样式
在drawable资源文件夹下新建一个 cursor_color.xml
文件
<?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>
在 EditText 中使用
<EditText
android:textCursorDrawable="@drawable/cursor_color"
android:hint="自定义光标颜色"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
EditText 取消背景
我们发现将 EditText android:textCursorDrawable
设置为"@null"之后,光标的样式会变得跟文字的颜色一样,如果我们将整个EditText的背景设置为"@null"之后,再给EditText添加 android:background="@null"
,如果EditText没有获取焦点看上去跟TextView效果一样。
全局修改EditText颜色
我们可以直接修改 Style.xml
中样式,来实现全局修改EditText颜色。
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<!--标题栏的颜色-->
<item name="colorPrimary">@color/colorPrimary</item>
<!--状态栏的颜色-->
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<!--EditText默认颜色-->
<item name="colorAccent">@color/colorAccent</item>
</style>
如果继承自Activity时自定义下划线
如果继承 Activity,上面的方式,虽然光标的颜色虽然还能修改,但是下划线的颜色却改不了。
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。当然,被选中时的下划线宽度要大一点。
<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,默认都为未选中状态**/
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);
}
}
});
我们可以将选中和未选中的状态封装到状态选择器中。在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的焦点监听代码删去就可以了。
About Me