You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android自定义属性配合selector选择器使用不生效如何解决

核心错误

你没有将自定义属性的运行时值同步到View的Drawable状态体系中。Android的Selector不会主动读取你通过TypedArray拿到的自定义属性值,它的规则匹配完全依赖View维护的Drawable状态集,自定义属性默认不会被加入这个状态集,所以Selector永远无法匹配到你写的规则。

修复步骤
    1. 声明对应自定义状态
      在原有attrs配置中补充自定义状态的声明,Selector匹配依赖这个状态标识:
<?xml version="1.0" encoding="utf-8"?>
<resources>    
    <!-- 自定义状态声明,供Selector匹配使用 -->
    <attr name="state_mycustom" format="boolean"/>
    <declare-styleable name="MyComponent">
        <attr name="mycustom" format="boolean"/>
    </declare-styleable>
</resources>
    1. 自定义View中同步状态
      在MyComponent类中重写onCreateDrawableState方法,把自定义属性的当前值合并到Drawable状态集;同时在属性值变化时主动调用refreshDrawableState()触发状态刷新:
public class MyComponent extends View {
    private boolean isMyCustom = false;

    public MyComponent(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyComponent);
        isMyCustom = typedArray.getBoolean(R.styleable.MyComponent_mycustom, false);
        typedArray.recycle();
    }

    // 动态修改mycustom属性值后必须调用refreshDrawableState()触发状态更新
    public void setMyCustom(boolean value) {
        if (isMyCustom != value) {
            isMyCustom = value;
            refreshDrawableState();
        }
    }

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        // 预留1个位置存储自定义状态
        int[] states = super.onCreateDrawableState(extraSpace + 1);
        // 合并自定义状态到状态集
        if (isMyCustom) {
            mergeDrawableStates(states, new int[]{R.attr.state_mycustom});
        } else {
            mergeDrawableStates(states, new int[]{-R.attr.state_mycustom});
        }
        return states;
    }
}
    1. 修正Selector的匹配属性
      把Selector中原来写的app:mycustom替换为自定义状态app:state_mycustom:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item app:state_mycustom="false">
        <!-- 对应false状态的Drawable -->
    </item>
    <item app:state_mycustom="true">
        <!-- 对应true状态的Drawable -->
    </item>
</selector>
子元素使用场景补充

如果需要在MyComponent的子View的Selector中使用这个自定义状态,只需要在子View的布局节点上添加如下配置,让子View同步父View的Drawable状态即可:

android:duplicateParentState="true"

内容的提问来源于stack exchange,提问作者LLL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:21:49