state_selected不生效的主因是view未主动调用setselected(),需在代码中(如onbindviewholder)手动控制;它不同于state_activated,不被系统自动管理,且易受焦点抢占、资源路径错误或主题覆盖影响。

selector 中 state_selected 不生效的常见原因
Android 的 state_selected 不像 state_pressed 或 state_checked 那样自动触发,它依赖 View 主动调用 setSelected(true) —— 也就是说,XML 里写了没用,代码不配合就永远不亮。
- ListView/RecyclerView 的 item 默认不会自动设置 selected 状态,即使你点了也不会变(除非你手动在
onBindViewHolder或getView里根据 position 设置) -
TextView、Button等普通控件默认忽略state_selected,因为它们不参与焦点/选择状态管理,除非你显式调用setSelected() - 如果父容器(比如
LinearLayout)设置了android:descendantFocusability="blocksDescendants",子 View 可能收不到 selection 事件传递
怎么让 state_selected 真正起作用
关键不是 XML 写得多漂亮,而是谁来控制 selected 状态。最典型场景是 RecyclerView 列表高亮当前选中项:
- 在 Adapter 的
onBindViewHolder中,根据当前 item 是否为选中项,调用holder.itemView.setSelected(isSelected) - 确保 ViewHolder 的根布局(如
ConstraintLayout)没有设置android:focusable="true"或android:clickable="true"却不处理点击逻辑——这会导致焦点抢占,干扰 selected 状态同步 - XML selector 文件必须放在
res/drawable/下,且根节点为selector,item中用android:state_selected="true"匹配
示例 selector(res/drawable/item_bg_selector.xml):
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@color/blue_500" />
<item android:drawable="@color/white" />
</selector>
state_selected 和 state_activated 的区别
很多人混淆这两个状态,结果样式始终不生效。核心差异在生命周期管理和系统支持:
-
state_selected是 View 级别的布尔状态,完全由你代码控制,不持久、不跨配置变更(比如横竖屏切换后丢失) -
state_activated是 ViewGroup(如ListView、RecyclerView)配合AbsListView.CHOICE_MODE_SINGLE或CHOICE_MODE_MULTIPLE自动管理的状态,会持久化选中项索引,且兼容 Android 3.0+ 的激活模式 - 如果你用的是
RecyclerView+ 自定义单选逻辑,state_selected更轻量;但若想复用系统级多选交互(比如长按进入选择模式),应优先用state_activated并配合setItemViewCacheSize避免 ViewHolder 复用导致状态错乱
selector 文件被忽略的隐藏坑
即使 XML 写对了、代码也调用了 setSelected(),样式仍可能不出现,常见于资源加载路径或主题干扰:
- 确保 View 的背景设为该 selector:
android:background="@drawable/item_bg_selector",而不是android:foreground或app:srcCompat - 如果项目启用了 Material Theme,某些组件(如
MaterialCardView)默认使用cardBackgroundColor,会覆盖 background,此时需显式设app:cardBackgroundColor="@android:color/transparent" - selector 中引用的颜色或 drawable 必须存在且未被资源压缩移除(检查
build.gradle中shrinkResources true是否误删了未直接引用的 selector 资源)
真正难的不是写 XML,而是理解 selected 状态本质是“你告诉系统这个 View 当前被逻辑选中”,系统不会替你做判断。漏掉一次 setSelected(false) 清理,或者 RecyclerView 滑动后没重置状态,样式就会粘滞或错位。










