0

这真的让我很困惑。我已将Button课程扩展如下:

public class MyButton extends Button {

    // Default colours/styles
    private int myButtonDrawable = R.drawable.button_drawable;
    private int myButtonTextColor = R.color.white_text;

    // Constructors
    public MyButton (Context context) {
        super(context);
    }

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyButton (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    // Override setEnabled to apply custom colors/styles
    @Override
    public void setEnabled (boolean enabled) {
        super.setEnabled(enabled);

        if (enabled) {
            this.setBackgroundResource(myButtonDrawable);
            this.setTextColor(getResources().getColor(myButtonTextColor));
        }

    }

因此,通过使用设置器,我可以为每个对象设置值,myButtonDrawable并且当我使用该方法启用按钮时(即当为真时),它们将被应用。myButtonTextColorMyButtonsetEnabled

但是,上面的代码不起作用。它与 logcat 一起崩溃

Caused by: android.view.InflateException: Binary XML file line #36: Error inflating class

该行发生错误

this.setTextColor(getResources().getColor(myButtonTextColor));

这真的很奇怪,因为如果我使用它就可以正常工作

this.setTextColor(getResources().getColor(R.color.white_text));

资源white_text定义为

<color name="white_text">#FFFFFFFF</color>

我不明白为什么用R.color.white_text类成员替换myButtonTextColor会导致活动崩溃。有人有什么想法吗?谢谢。

4

1 回答 1

2

编辑:您正在扩展Button. Buttonextends TextView,它从其 XML 属性中读取并setEnabled(boolean) 在其构造函数中调用。但是,您已经重写setEnabled()并且该方法现在引用由初始化程序在您的子类中定义的字段。

子类的初始化程序不会在超类的构造函数之前运行。因此,在第一次setEnabled()由超类构造函数调用时,myButtonTextColor具有默认值并使用它来解析它Resources.getColor()会抛出错误。

如果您坚持在代码中执行此操作,则可以将 if 语句移动到子类的构造函数中:

public MyButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    if (isEnabled()) {
        setBackgroundResource(myButtonDrawable);
        //FYI, there is a setTextColor method that accepts a color ID.
        setTextColor(myButtonTextColor);
    }
}

因为在调用子类的构造函数时,保证初始化器已经运行,并且超类构造函数已经从 XML 中解析了属性。

如果您想更深入地了解 Java 在这方面的工作原理,这里有一个很好的解释。


对于您想要做的事情,有一种更好的方法。使用标准 AndroidButton并在您的 XML(或代码)中,将选择器设置为按钮的背景和颜色。您可以为按钮的启用状态定义外观——以及许多其他状态,包括按下、聚焦等。Android 将为您处理更改外观。

在您的活动中(或者您可以在 XML 中执行此操作):

Button button = new Button();
button.setTextColor(R.drawable.button_text_color);
button.setBackgroundResource(R.drawable.button_background);

可绘制/button_text_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:color="@color/white_text" />
    <item android:color="@color/grey_text" />
</selector>

可绘制/button_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="true" android:background="@drawable/button_drawable"/> 
     <item android:background="@drawable/button_disabled_drawable"/> 
</selector>
于 2013-08-30T15:28:37.173 回答