注: Android サポート ライブラリ v22.1.0 を使用し、API レベル 11 以上をターゲットにしていますか? 最後の更新までスクロールします。
私のアプリケーション スタイルは暗い Theme.Holo に設定されており、リスト ビューのチェック ボックスを Theme.Holo.Light スタイルにしたいと考えています。カスタム スタイルを作成しようとしているわけではありません。以下のコードは機能していないようで、何も起こりません。
最初は、システムがこのような動作を示す理由は明らかではないかもしれませんが、実際にメカニズムを調べると、簡単に推測できます。順を追って説明します。
Widget.Holo.Light.CompoundButton.CheckBox
まず、スタイルの定義を見てみましょう。より明確にするために、「通常の」(ライト以外の) スタイル定義も追加しました。
<style name="Widget.Holo.Light.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox" />
<style name="Widget.Holo.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox" />
ご覧のとおり、どちらもWidget.CompoundButton.CheckBox
別の名前でラップするだけの空の宣言です。それでは、その親スタイルを見てみましょう。
<style name="Widget.CompoundButton.CheckBox">
<item name="android:background">@android:drawable/btn_check_label_background</item>
<item name="android:button">?android:attr/listChoiceIndicatorMultiple</item>
</style>
このスタイルは、背景とボタンの両方のドローアブルを参照します。btn_check_label_background
は単なる 9 パッチなので、この件に関してはあまり興味深いものではありません。ただし、は、現在のテーマ?android:attr/listChoiceIndicatorMultiple
に基づく一部の属性(これを理解することが重要です) が の実際の外観を決定することを示しています。CheckBox
テーマ属性と同様listChoiceIndicatorMultiple
に、テーマごとに 1 つずつ (または、親テーマから継承された場合はなし)、複数の宣言があります。これは次のようになります (明確にするために他の属性は省略されています)。
<style name="Theme">
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check</item>
...
</style>
<style name="Theme.Holo">
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_dark</item>
...
</style>
<style name="Theme.Holo.Light" parent="Theme.Light">
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_light</item>
...
</style>
ここで本当の魔法が起こります: テーマのlistChoiceIndicatorMultiple
属性に基づいて、 の実際の外観CheckBox
が決定されます。表示されている現象は簡単に説明できます。外観はテーマベースであり (スタイルベースではありませんTheme.Holo
。これは空の定義に過ぎないためです)、 から継承しているため、常にCheckBox
テーマに一致する外観が得られます。
CheckBox
の外観を Holo.Light バージョンに変更する場合は、それらのリソースのコピーを取得し、それらをローカル アセットに追加して、カスタム スタイルを使用して適用する必要があります。
2番目の質問について:
また、アプリケーションにスタイルを設定すると、個々のウィジェットにスタイルを設定できますか?
もちろん、アクティビティまたはアプリケーション セットのスタイルをオーバーライドします。
チェックボックスウィジェットにテーマ(画像付きのスタイル)を設定する方法はありますか? (...) このセレクタを使用する方法はありますか: link ?
アップデート:
もう一度言いますが、Android の内部リソースに依存するべきではありません。好きなように内部名前空間にアクセスできないのには理由があります。
ただし、結局、システム リソースにアクセスする方法は、名前による ID ルックアップを行うことです。次のコード スニペットを検討してください。
int id = Resources.getSystem().getIdentifier("btn_check_holo_light", "drawable", "android");
((CheckBox) findViewById(R.id.checkbox)).setButtonDrawable(id);
btn_check_holo_light
最初の行は、実際にはドローアブル リソースのリソース ID を返します。これが の外観を決定するボタン セレクタであることを前に確認したのでCheckBox
、ウィジェットで「ボタン ドローアブル」として設定できます。結果は、xml でアプリケーション、アクティビティ、またはウィジェットに設定したテーマ/スタイルに関係なくCheckBox
、バージョンの外観を備えたです。Holo.Light
これはボタン ドローアブルのみを設定するため、他のスタイルを手動で変更する必要があります。たとえば、テキストの外観に関して。
結果を示すスクリーンショットの下。一番上のチェックボックスは上記の方法を使用します (xml でテキストの色を手動で黒に設定しましたHolo
)。

アップデート2:
Support Library v22.1.0 の導入により、作業が非常に簡単になりました! リリースノートからの引用 (私の強調):
Lollipop は、XML 属性を使用してビューごとにテーマを上書きする機能を追加しました。これandroid:theme
は、明るいアクティビティの暗いアクション バーなどに非常に便利です。現在、AppCompat ではandroid:theme
、ツールバー (app:theme
以前に使用されていたものは非推奨) に使用できるようになり、さらに良いandroid:theme
ことに、API 11 以降のデバイスのすべてのビューがサポートされます。
つまり、ビューごとにテーマを適用できるようになったため、元の問題の解決がはるかに簡単になりました。関連するビューに適用したいテーマを指定するだけです。つまり、元の質問のコンテキストで、以下の結果を比較してください。
<CheckBox
...
android:theme="@android:style/Theme.Holo" />
<CheckBox
...
android:theme="@android:style/Theme.Holo.Light" />
CheckBox
アクティビティまたはアプリケーションに設定されている実際のテーマに関係なく、1 つ目はダーク テーマで使用されているかのようにスタイル設定され、2 つ目はライト テーマで使用されているかのようにスタイル設定されます。
もちろん、Holo テーマを使用するのではなく、Material を使用する必要があります。