2

ここで数時間検索してこれとあれをテストした後、問題を解決することも、問題に当てはまる質問/回答を見つけることもできませんでしたが、間違った検索用語しか使用していない可能性があるため、ヒントに感謝しています正しい方向に!

基本的には、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);

動作しますが、複雑であり、それが意図された方法である場合、それは悲しいです...;)

4

2 に答える 2

1

これを試しましたか?

<style name="Theme.MyApp" parent="Theme.Sherlock">
...
</style>

<style name="Theme.MyApp.Light" parent="Theme.Sherlock.Light">
...
</style>

<style name="TextNormal" parent="Theme.MyApp">
    <item name="android:textColor">#ffffffff</item>
</style>

<style name="TextNormal" parent="Theme.MyApp.Light">
    <item name="android:textColor">#ff000000</item>
</style>

layout.xmlでの参照は次のとおりです。

<TextView style="@style/TextNormal" .../>
于 2012-05-22T06:55:27.060 に答える
1

私自身の質問に答える:

これを見つけた

したがって、私の--working --switchstatementの代わりに、まだいくつかのコードが必要ですが、少なくともテーマIDのハードコーディングはありません...->このスニペットでgetThemedStyleを更新しました

public static int getThemedStyle(int normalStyle) {
 Resources.Theme theme = appContext.getTheme();
 TypedValue styleID = new TypedValue();
 if (theme.resolveAttribute(R.attr.TextAppRed, styleID, true)) return styleID.data;
  else return normalStyle;
} //getThemedStyle
于 2012-05-22T18:07:45.693 に答える