RadioButton在Android 4.4及以下调用setButtonDrawable(null)无效的问题

在 Android 4.4 系统下,Java 代码中调用 RadioButton.setButtonDrawable(null) 无效,而在 xml 布局中设置元素属性 android:button="@null" 有效,并且在 Android 5.0+ 系统上调用 Java 代码也有效。

初步分析,应该是系统差异导致的,因此直接比较 Android 4.4 和 Android 5.0 系统代码中 RadioButton.setButtonDrawable() 方法的差异。

Android 4.4 版本的代码如下:

public void setButtonDrawable(Drawable d) {
    if (d != null) {
        if (mButtonDrawable != null) {
            mButtonDrawable.setCallback(null);
            unscheduleDrawable(mButtonDrawable);
        }
        d.setCallback(this);
        d.setVisible(getVisibility() == VISIBLE, false);
        mButtonDrawable = d;
        setMinHeight(mButtonDrawable.getIntrinsicHeight());
    }
    refreshDrawableState();
}

可以看见,在 Android 4.4 系统中,在 setButtonDrawable() 方法中传入 null,是没有任何作用的,仍然会显示 RadioButton 默认的样式。
而 XML 布局中设置 android:button="@null",会在 RadioButton 调用构造方法初始化的时候,就将预设样式的值设置为 null,这就是为什么 Java 代码设置无效而 XML 布局设置有效的原因。

而 Android 5.0 的代码如下:

public void setButtonDrawable(Drawable d) {
    if (mButtonDrawable != d) {
        if (mButtonDrawable != null) {
            mButtonDrawable.setCallback(null);
            unscheduleDrawable(mButtonDrawable);
        }
        mButtonDrawable = d;
        if (d != null) {
            d.setCallback(this);
            d.setLayoutDirection(getLayoutDirection());
            if (d.isStateful()) {
                d.setState(getDrawableState());
            }
            d.setVisible(getVisibility() == VISIBLE, false);
            setMinHeight(d.getIntrinsicHeight());
            applyButtonTint();
        }
    }
}

可以看到,系统会先比较传入的值和预设样式的值(mButtonDrawable)是否相等,这里传入为 null,和预设值当然不相等,然后就将传入的值赋值给预设样式。当 RadioButton 显示到界面上时,就没有预设样式。

知道原因后,现在来看看如何解决 Android 4.4 系统上调用 RadioButton.setButtonDrawable(null) 代码无效的问题。

RadioButton 预设样式的值 mButtonDrawable 是在抽象父类 CompoundButton 中定义的,因此,我们要做的就是拿到这个属性字段,然后将其设置为 null 即可,代码很简单:

if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
    try {
        Field field = radioButton.getClass().getSuperclass().getDeclaredField("mButtonDrawable");
        field.setAccessible(true);
        field.set(radioButton, null);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/18/android-4-4-radiobutton-setbuttondrawable-null-invalid/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
RadioButton在Android 4.4及以下调用setButtonDrawable(null)无效的问题
在 Android 4.4 系统下,Java 代码中调用 RadioButton.setButtonDrawable(null) 无效,而在 xml 布局中设置元素属性 android:button="@null" 有效,……
<<上一篇
下一篇>>
文章目录
关闭
目 录