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したがって、セッターを使用することで、myButtonTextColor各オブジェクトの値を設定できMyButton、メソッドを使用してボタンを有効にしたsetEnabledとき (つまり、true のとき) に値が適用されます。

ただし、上記のコードは機能しません。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ます。 ButtonextendsTextViewは 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);

drawable/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>

drawable/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 に答える