方法:カスタムウィジェットのテーマ(スタイル)アイテムを定義する


86

アプリケーション全体で広く使用されているコントロールのカスタムウィジェットを作成しました。ウィジェットクラスはImageButton、いくつかの簡単な方法で派生し、拡張します。ウィジェットの使用時に適用できるスタイルを定義しましたが、テーマを使用して設定したいと思います。でR.styleable私のようなウィジェットスタイル属性参照imageButtonStyleとしますtextViewStyle。私が書いたカスタムウィジェット用にそのようなものを作成する方法はありますか?

回答:


209

はい、1つの方法があります:

ウィジェットの属性の宣言があるとします(でattrs.xml):

<declare-styleable name="CustomImageButton">
    <attr name="customAttr" format="string"/>
</declare-styleable>

スタイル参照に使用する属性を(でattrs.xml)宣言します。

<declare-styleable name="CustomTheme">
    <attr name="customImageButtonStyle" format="reference"/>
</declare-styleable>

ウィジェットのデフォルト属性値のセットを(でstyles.xml)宣言します。

<style name="Widget.ImageButton.Custom" parent="android:style/Widget.ImageButton">
    <item name="customAttr">some value</item>
</style>

カスタムテーマを宣言する(でthemes.xml):

<style name="Theme.Custom" parent="@android:style/Theme">
    <item name="customImageButtonStyle">@style/Widget.ImageButton.Custom</item>
</style>

この属性をウィジェットのコンストラクター(内CustomImageButton.java)の3番目の引数として使用します。

public class CustomImageButton extends ImageButton {
    private String customAttr;

    public CustomImageButton( Context context ) {
        this( context, null );
    }

    public CustomImageButton( Context context, AttributeSet attrs ) {
        this( context, attrs, R.attr.customImageButtonStyle );
    }

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

        final TypedArray array = context.obtainStyledAttributes( attrs,
            R.styleable.CustomImageButton, defStyle,
            R.style.Widget_ImageButton_Custom ); // see below
        this.customAttr =
            array.getString( R.styleable.CustomImageButton_customAttr, "" );
        array.recycle();
    }
}

次に、(AndroidManifest.xmlで)Theme.Customを使用するすべてのアクティビティに適用する必要がありますCustomImageButton

<activity android:name=".MyActivity" android:theme="@style/Theme.Custom"/>

それで全部です。今CustomImageButtonからデフォルトの属性値をロードしようとするcustomImageButtonStyle現在のテーマの属性。テーマまたは属性の値にそのような属性が見つからない場合は@null、の最後の引数obtainStyledAttributesが使用されますWidget.ImageButton.Custom。この場合は。

すべてのインスタンスとすべてのファイル(を除くAndroidManifest.xml)の名前を変更できますが、Androidの命名規則を使用することをお勧めします。


4
テーマを使わずにまったく同じことをする方法はありますか?私はいくつかのカスタムウィジェットを持っていますが、ユーザーがこれらのウィジェットを好きなテーマで使用できるようにしたいと思います。あなたが投稿した方法でそれを行うには、ユーザーが私のテーマを使用する必要があります。
theDazzler 2013

3
@theDazzler:開発者が使用できるライブラリを意味する場合、開発者は独自のテーマを作成し、テーマのstyle属性を使用してウィジェットのスタイルを指定できます(customImageButtonStyleこの回答)。これが、Androidでアクションバーがカスタマイズされる方法です。また、実行時にテーマを変更することを意味する場合、このアプローチでは不可能です。
マイケル

@ Michael、はい私は開発者が使用できるライブラリを意味しました。あなたのコメントは私の問題を解決しました。ありがとう!
theDazzler 2013

30
これらすべてについて最も驚くべきことは、Googleの誰かがこれは大丈夫だと思っていることです。
グレンメイナード

1
name="CustomTheme"declare-styleable任意の目的を果たすラッパー属性?どこにも使われていないので、それは組織のためだけのものです。さまざまなウィジェットのすべてのスタイル属性を1つのラッパーに入れることはできますか?
tenfour04 2017年

4

マイケルの優れた答えに加えて、別の側面は、テーマのカスタム属性をオーバーライドすることです。すべてがカスタム属性「custom_background」を参照する多数のカスタムビューがあるとします。

<declare-styleable name="MyCustomStylables">
    <attr name="custom_background" format="color"/>
</declare-styleable>

テーマでは、値が何であるかを定義します

<style name="MyColorfulTheme" parent="AppTheme">
    <item name="custom_background">#ff0000</item>
</style>

または

<style name="MyBoringTheme" parent="AppTheme">
    <item name="custom_background">#ffffff</item>
</style>

スタイルで属性を参照できます

<style name="MyDefaultLabelStyle" parent="AppTheme">
    <item name="android:background">?background_label</item>
</style>

疑問符に注意してください。これは、次のようにAndroid属性の参照にも使用されます。

?android:attr/colorBackground

ほとんどの人が気付いているように、ハードコードされた色の代わりに@color参照を使用できます(おそらくそうすべきです)。

だから、なぜ

<item name="android:background">@color/my_background_color</item>

実行時に「my_background_color」の定義を変更することはできませんが、テーマは簡単に切り替えることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.