在扩展按钮类中设置按钮颜色

时间:2013-08-30 14:30:29

标签: android button colors extension-methods

这让我很困惑。我已将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));
        }

    }

因此,通过使用setter,我可以为每个myButtonDrawable对象设置myButtonTextColorMyButton的值,当我使用方法setEnabled启用按钮时,它们将被应用(即真的时候)。

但是,上面的代码不起作用。它与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会导致活动崩溃。有人有任何想法吗?感谢。

1 个答案:

答案 0 :(得分:2)

编辑:您正在扩展ButtonButton扩展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中解析了属性。

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

<小时/> 对于您想要做的事情,有一种更好的方法。使用标准Android Button并在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>