Selector对于大家来说都是比较熟悉的,常见的会用在Button或者ListView,少见的也有RadioButton等等,主要应用于不同状态下的样式设置。
一、官方介绍
先来看看官网:https://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
其实它是可绘制对象资源中的状态列表(StateListDrawable )
StateListDrawable
是在 XML 中定义的可绘制对象,它根据对象的状态,使用多个不同的图像来表示同一个图形。例如,Button
小部件可以是多种不同状态(按下、聚焦或这两种状态都不是)中的其中一种,而且可以利用状态列表可绘制对象为每种状态提供不同的背景图片。
您可以在 XML 文件中描述状态列表。每个图形由单一 <selector>
元素内的 <item>
元素表示。每个 <item>
均使用各种属性来描述应用作可绘制对象的图形的状态。
在每个状态变更期间,将从上到下遍历状态列表,并使用第一个与当前状态匹配的项目 —此选择并非基于“最佳匹配”,而是选择符合状态最低条件的第一个项目。
文件位置:
res/drawable/filename.xml
文件名用作资源 ID。
编译的资源数据类型:
指向 StateListDrawable
的资源指针。
资源引用:
在 Java 中:R.drawable.filename
在 XML 中:@[package:]drawable/filename
语法:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize=["true" | "false"]
android:dither=["true" | "false"]
android:variablePadding=["true" | "false"] >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_hovered=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_activated=["true" | "false"]
android:state_window_focused=["true" | "false"] />
</selector>
元素:
<selector>
必备。这必须是根元素。包含一个或多个 <item>
元素。
<item>
定义要在某些状态期间使用的可绘制对象,如其属性所述。必须是 <selector>
元素的子项。
item属性:
android:drawable可绘制对象资源。必备。引用可绘制对象资源。
android:state_**这里有九种情况。官网写的比较是专业,所以后面还是自己给出了对他的理解,比较容易看懂的。
二、对android:state_**的清晰理解:
android:state_pressed 是否按下,如一个按钮触摸或者点击。
android:state_focused 是否取得焦点,比如用户选择了一个文本框。
android:state_hovered 光标是否悬停,通常与focused state相同,它是4.0的新特性
android:state_selected 被选中,它与focus state并不完全一样,如一个list view 被选中的时候,它里面的各个子组件可能通过方向键,被选中了。
android:state_checkable 组件是否能被check。如:RadioButton是可以被check的。
android:state_checked 被checked了,如:一个RadioButton可以被check了。
android:state_enabled 能够接受触摸或者点击事件
android:state_activated 被激活(这个麻烦举个例子,不是特明白)
android:state_window_focused 应用程序是否在前台,当有通知栏被拉下来或者一个对话框弹出的时候应用程序就不在前台了
注意:如果有多个item,那么程序将自动从上到下进行匹配,最先匹配的将得到应用。(不是通过最佳匹配)
如果一个item没有任何的状态说明,那么它将可以被任何一个状态匹配。
三、常见用法:
举例Button的正常样式跟点击样式,这里举例就两种样式,在项目中也可能设置Button的其他state下的样式,下面只是为了方便介绍。
1、固定的样式设置:不可变的,只需要一个xml (item_bg.xml)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="6dp" />
<padding android:bottom="10dp" android:left="20dp" android:right="20dp" android:top="10dp" />
<solid android:color="@color/white" />
<stroke android:width="1dp" android:color="@color/green_deep_color" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:radius="6dp" />
<solid android:color="@color/white" />
<padding android:bottom="10dp" android:left="20dp" android:right="20dp" android:top="10dp" />
<stroke android:width="1dp" android:color="@color/black_deep" />
</shape>
</item>
</selector>
这里须有pressed的效果跟下面item没有设置的默认两种样式
2、可选择的样式设置:可选的,需要三个xml (item_bg.xml,item_bg_normal.xml,item_bg_pressed.xml)
item_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/popup_item_bg1_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/popup_item_bg1_normal" />
</selector>
item_bg_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="6dp" />
<solid android:color="@color/white" />
<padding
android:bottom="10dp"
android:left="20dp"
android:right="20dp"
android:top="10dp" />
<stroke
android:width="1dp"
android:color="@color/black_deep" />
</shape>
item_bg_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="6dp" />
<padding
android:bottom="10dp"
android:left="20dp"
android:right="20dp"
android:top="10dp" />
<solid android:color="@color/white" />
<stroke
android:width="1dp"
android:color="@color/green_deep_color" />
</shape>
有人说用这要三个xml不觉得蛋疼吗,我也觉得有点,不过还是看具体分析来的。如果你要求要在代码中可以进行对样式的选中呢?这样就要三个了,如果没有说后续要进行可选的,我还是建议用第一种,方便即少xml,资源不会太多。
3、另外一种是通过代码实现,这里就不详细介绍了,网上有很多文章介绍的蛮详细