ここで数時間検索してこれとあれをテストした後、問題を解決することも、問題に当てはまる質問/回答を見つけることもできませんでしたが、間違った検索用語しか使用していない可能性があるため、ヒントに感謝しています正しい方向に!
基本的には、2つのテーマ(ダークとライト)を使用するアプリに関するものです。一部のTextViewはステータスを表示します。ステータスはオンまたはオフにできます。状態をよりよく認識するには、テキストの色に状態を反映させる必要があります。オフの場合は赤、オフの場合は赤。オンの場合は緑。
テーマやスタイルを使用しなかったときは、赤い色にTextViewの.setColor(#ffff0000)などを使用しました...
それから私はさまざまな状況での視認性を高めるためにダーク/ライトテーマを利用し始めました-たとえば、白い背景の屋外の黒いテキストは読みやすくなっています。
したがって、私は2つのテーマを定義し、textAppearanceを上書きしました。
<style name="Theme.MyApp" parent="Theme.Sherlock">
...
<item name="android:textAppearance">@style/TextNormal</item>
...
</style>
<style name="Theme.MyApp.Light" parent="Theme.Sherlock.Light">
...
<item name="android:textAppearance">@style/TextNormalLight</item>
...
<style name="TextNormal">
<item name="android:textColor">#ffffffff</item>
</style>
<style name="TextNormalLight">
<item name="android:textColor">#ff000000</item>
</style>
これは正常に機能し、「通常の」テキストビューはテーマに応じて正しい色で表示されます。ここまでは順調ですね!
TextViewのsetColorを使用する代わりに、.setTextAppearance tv.setTextAppearance(getSherlockActivity()、R.style.TextRed);を使用するように切り替えました。
いくつかのスタイルを定義しました(1つだけ貼り付け、他はTextGreen、...):
<style name="TextRed">
<item name="android:textColor">#ffff0000</item>
</style>
これも問題なく動作します!
そしてついに私の問題にたどり着くために:
テーマに応じて「赤」の色を変えたい…
だから私はTextRedスタイルを維持し、Lightテーマで使用するスタイルを追加します。テストのために、奇妙な色を作成して、それが機能しているかどうかを確認します。
<style name="TextRedLight">
<item name="android:textColor">#ffffff00</item>
</style>
これは、TextViewの.setTextAppearanceの周りにswitchステートメントを配置し、選択したテーマに応じて正しいスタイルを選択した場合にも機能します-擬似コード:
switch (currentheme) {
case Dark: tv.setTextAppearance(... R.style.TextRed); break;
case Light: tv.setTextAppearance(... R.style.TextRedLight); break;
}
そして今の課題/質問は-どうすればswitchステートメントを回避できますか?
layout.xmlファイルでスタイルを参照する場合、?を使用できます。現在のテーマを尊重するための参照...(「@」の代わりに)
この場合、実行時にスタイルを設定し、テーマを尊重する必要があります。したがって、xmlではなくコードで行う必要がありますが、setTextAppearanceは、テーマのワイルドカード+ IDではなく、スタイルのIDのみを受け入れます。 ..
そして、これは私が立ち往生しているところです...はい、クラスをラップしてコード内の1行に保持し、このクラスのテーマ検出/ switchステートメントを「非表示」にすることができますが、その一方で、Androidの複雑なスタイル/テーマのアーキテクチャには、この問題の解決策もあるはずですよね...?
テーマとスタイルを使用することは、いくつかの拡張された作業を実行するためにヘルパークラスまたはswitch / ifステートメントが必要である限り、少し無意味に思えます...
ヒント/アイデアをありがとう!!!
編集1-Tomášの回答後: style.xmlを更新:
<style name="TextNormal" parent="Theme.ARMoDroid">
<item name="android:textColor">#ffffffff</item>
</style>
<style name="TextNormal" parent="Theme.ARMoDroid.Light">
<item name="android:textColor">#ff000000</item>
</style>
<style name="TextRed" parent="Theme.ARMoDroid">
<item name="android:textColor">#ffff0000</item>
</style>
<style name="TextRed" parent="Theme.ARMoDroid.Light">
<item name="android:textColor">#ffffff00</item>
</style>
layout.xmlで割り当てられたTextNormalを持つTextViews、または両方のテーマからTextNormalを参照する場合:
<item name="android:textAppearance">@style/TextNormal</item>
赤いテキストを使用する場合も、以前と同じように機能します(この異なるアプローチで)。
しかし、最初の問題はまだ解決していません。(実行時に)テキストの色を赤に変更したい場合は、
tv.setTextAppearance(getActivity(),R.style.TextRed)
常にTextRedの最後の定義を使用します。したがって、上記の定義では、テキストは#ffffff00->黄色で色付けされます。2つのTextRed定義の順序を入れ替えると、最後の定義(#ffff0000)が使用され、テキストは赤になります。
したがって、実行時にスタイルを設定する場合、setTextAppearanceはテーマ対応ではありません。現在のテーマと2つの定義されたスタイルを区別しません。
テーマに応じて異なるtextcolor-valuesを持つ1つのスタイルを定義でき、選択したテーマに応じて、スタイルがlayout.xmlで割り当てられているか、テーマセットのこのスタイルがデフォルトである限り、正しく色付けされます。
ただし、実行時にコードでスタイルを動的に切り替える場合でも、上記のswitchステートメントのようなものが必要です。選択されているテーマを検出し、テーマに応じて、テキストビューに別のスタイルを適用します。
私が達成したいのは、現在のテーマに応じて正しい「TextRed」スタイルを選択する必要があるということです。したがって、テーマの認識をハードコーディングする必要はありません...新しいテーマが追加されたら、前述のswitch-statementも更新する必要があります...
編集2:私の現在の「解決策」
私は現在の解決策も投稿するかもしれないと思っていましたが、それは実際には良い解決策ではありません-それは機能していますが-しかしそれは各スタイルのカスタムコードであり、別のテーマではさらに多くのコードです...
ヘルパー関数は次のようになります。
public static int getThemedStyle(int normalStyle) {
if (prefs==null) { prefs = PreferenceManager.getDefaultSharedPreferences(appContext); }
int theme = Integer.valueOf(prefs.getString("GUI_Theme","0"));
if (theme==0) return normalStyle; //dark theme
else { //return correct Light-Theme Style
switch (normalStyle) {
case R.style.TextNormal: return R.style.TextNormalLight;
case R.style.TextRed: return R.style.TextRedLight;
case R.style.TextOrange: return R.style.TextOrangeLight;
case R.style.TextGreen: return R.style.TextGreenLight;
case R.style.TextYellow: return R.style.TextYellowLight;
case R.style.TextBlue: return R.style.TextBlueLight;
default: return normalStyle;
} //switch
} //else theme==0
} //getThemedStyle
フラグメントでは、onCreateで上記の関数を呼び出して、スタイル参照をキャッシュします。
styleRed = preferences.getThemedStyle(R.style.TextRed);
styleOrange = preferences.getThemedStyle(R.style.TextOrange);
styleGreen = preferences.getThemedStyle(R.style.TextGreen);
最後に、次を使用してスタイルを割り当てます。
tv.setTextAppearance(getSherlockActivity(), styleRed);
動作しますが、複雑であり、それが意図された方法である場合、それは悲しいです...;)