概述
selector的存在,使得控件在不同状态有不同的展现形式,大概有以下几种形式
-
android:state_pressed 控件点击状态,可以为true或false
-
android:state_enabled 控件使能状态,可以为true或false
-
android:state_selected 控件选中状态,可以为true或false
-
android:state_focused 控件获得焦点状态,可以为true或false
-
android:state_checked 控件勾选状态,可以为true或false,主要用于CheckBox和RadioButton,true表示已被勾选,false表示未被勾选
-
android:state_checkable 控件可勾选状态,可以为true或false
-
android:state_window_focused 设置当前窗口是否获得焦点状态,true表示获得焦点,false表示未获得焦点,例如拉下通知栏或弹出对话框时,当前界面就会失去焦点;另外,ListView的ListItem获得焦点时也会触发true状态,可以理解为当前窗口就是ListItem本身
-
android:state_activated 控件是否被激活状态,true表示被激活,false表示未激活,API Level 11及以上才支持,可通过代码调用控件的setActivated(boolean)方法设置是否激活该控件
-
android:state_hovered 控件鼠标悬停状态,true表示鼠标在上面滑动,默认为false,API Level 14及以上才支持
巧用state_selected
实际上state_selected也很好用。举个例子
有这么一种情况,有个点赞按钮,有3种状态,1、已赞(红色),2、未赞(灰色),3、赞按下(浅红)
很明显状态3 android:state_pressed,那状态1和2用什么比较好呢?
一种写法可以这样
Drawable drawable = ContextCompat.getDrawable(getContext(),islike
? R.drawable.like_pressed : R.drawable.like_normal);
setImageDrawable(drawable);
实际上,我们可以使用 android:state_selected来优雅的实现这个需求,我们可以这么写
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/like_selected" android:state_selected="true" />
<item android:drawable="@drawable/like_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/like_normal" />
</selector>
这样我们的代码只要写
setSelected(islike);
就可以了,我们主观认为selected状态就是已赞状态。
但是这么写,存在一个坑。当从“已赞”状态,切换到“赞”按下的状态的时候,按钮不会发生任何变化
在“已赞”状态(selected),我们按下按钮,会切换到pressed,此时按钮的状态既是selected也是pressed,那么系统会如何选择呢?系统会从上到下来匹配
,所以系统发现like_selected和现在的状态符合,他就会选择这个drawable,所以按钮没有发生任何变化
如何解决这个问题呢?只要在selector里面把android:state_pressed写在前面就可以了.代码如下
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/like_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/like_selected" android:state_selected="true" />
<item android:drawable="@drawable/like_normal" />
</selector>
记住,优先显示的状态要写在上面,android来匹配状态是从上到下来的
多条件item
其实针对上面那个问题,还有中解决方案,如下所示
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/like_selected" android:state_selected="true" android:state_pressed="false"/>
<item android:drawable="@drawable/like_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/like_normal" />
</selector>
相信大家一看就明白了,对于某个图片,我们可以设置多个条件,多个条件同时满足才会选此图片,整个selector的匹配过程就类似于
if(){
}else if()
{
}else if()
{
}
总结
1、android:state_selected用来解决2态问题很合适
2、selector的匹配是从上到下的,匹配到一个就结束
3、selector的每个item都可以设置多个条件,条件之间是且的关系,同时满足才会匹配到此item