2017-03-21 19 views
8

が、私はこのように、私のAndroidアプリに(動的)のテーマを使用しています:設定のテーマの色を動的

my_layout.xml(抜粋):

<TextView 
    android:id="@+id/myItem" 
    style="?my_item_style" /> 

attrs.xml(抜粋) :

<attr name="my_item_style" format="reference" /> 

themes.xml(抽出物):

<style name="MainTheme.Blue"> 
     <item name="my_item_style">@style/my_item_style_blue</item> 
</style> 

<style name="MainTheme.Green"> 
     <item name="my_item_style">@style/my_item_style_green<item> 
</style> 

のstyles.xml(抜粋):あなたが見ることができるよう

<style name="my_item_style_blue"> 
     <item name="android:textColor">@color/my_blue</item> 
</style> 

<style name="my_item_style_green"> 
     <item name="android:textColor">@color/my_blue</item> 
</style> 

だから、私は動的にテーマを設定しています。私はこのクラスを使用しています:

public class ThemeUtils { 

    private static int sTheme; 
    public final static int THEME_BLUE = 1; 
    public final static int THEME_GREEN = 2; 

    public static void changeToTheme(MainActivity activity, int theme) { 
     sTheme = theme; 
     activity.startActivity(new Intent(activity, MyActivity.class)); 
    } 

    public static void onActivityCreateSetTheme(Activity activity) 
    { 
     switch (sTheme) 
     { 
      default: 
      case THEME_DEFAULT: 
      case THEME_BLUE: 
       activity.setTheme(R.style.MainTheme_Blue); 
       break; 
      case THEME_GREEN: 
       activity.setTheme(R.style.MainTheme_Green); 
       break; 
     } 
    } 

}

私が知りたいのは何、コード内でこの(変更のテーマカラーを)行う方法方法はありますか?は、例えば、私はコード(抜粋)は以下のいる:

((TextView) findViewById(R.id.myItem)).setTextColor(R.color.blue); 

これは、利用可能なテーマのためswitchコマンドを使用して、テーマの正しい色を返しますいくつかのヘルパーメソッドによって行うことができます。しかし、より良い、より良い、そしてより速い方法があるかどうかを知りたいと思います。

ありがとうございます!

+1

ここではテーマを動的に設定していますか?あなたもそのコードを共有できますか? – azizbekian

+0

@azizbekian私はそれが私の質問に関連しているとは思わないが、私はThemeUtilsクラスを追加しました。 – Tom11

答えて

4

public static int getColor(String colorName) { 
    Context ctx = getContext(); 
    switch (sTheme) { 
     default: 
     case THEME_DEFAULT: 
      return ctx.getResources().getIdentifier("BLUE_" + colorName, "color", ctx.getPackageName()); 
     case THEME_BLUE: 
      return ctx.getResources().getIdentifier("BLUE_" + colorName, "color", ctx.getPackageName()); 
     case THEME_GREEN: 
      return ctx.getResources().getIdentifier("GREEN_" + colorName, "color", ctx.getPackageName()); 
    } 
} 

これが私のテーマ(私は接頭辞を使用)に応じた色を返します。

3

私はcorectly理解していれば、あなたが

  1. 、テーマからスタイルを抽出する方法を探しているが言ったスタイルから(テキストの色)の値を抽出します。

// Extract ?my_item_style from a context/activity. 
final TypedArray a = context.obtainStyledAttributes(new int[] { R.attr.my_item_style }); 
@StyleRes final int styleResId = a.getResourceId(0, 0); 
a.recycle(); 

// Extract values from ?my_item_style. 
final TypedArray b = context.obtainStyledAttributes(styleResId, new int[] { android.R.attr.textColor }); 
final ColorStateList textColors = b.getColorStateList(0); 
b.recycle(); 

// Apply extracted values. 
if (textColors != null) { 
    textView.setTextColor(textColors); 
} 

ノートのカップル:

  1. TypedArrayは、古いAPIレベルで色の状態のリストに、サポートベクトルドローアブルとテーマの参照を取得してサポートしていません。 AppCompat内部APIを使用する場合は、TintTypedArrayを試してみてください。
  2. いつもint[]を割り当てるのは高価です。static finalにしてください。
  3. 複数の属性を一度に解決したい場合は、属性の配列をソートする必要があります。それ以外のときはクラッシュします。 <declare-styleable>はそのような配列と対応するインデックスを生成します。
0

IntentでテーマIDを渡すのはどうですか?onCreate

Intent intent = new Intent(activity, MyActivity.class); 
intent.putExtra("theme", R.style.MainTheme_Green); 
activity.startActivity(intent); 

そして:

// assuming that MainTheme_Blue is default theme 
setTheme(getIntent().getIntExtra("theme", R.style.MainTheme_Blue)); 
1

あなたはこのMultipleThemeMaterialDesignデモをチェックしましたか?

enter image description here

SettingActivity:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    Preferences.applyTheme(this); 
    getDelegate().installViewFactory(); 
    getDelegate().onCreate(savedInstanceState); 
    super.onCreate(savedInstanceState); 
    setToolbar(); 
    addPreferencesFromResource(R.xml.preferences); 
    Preferences.sync(getPreferenceManager()); 
    mListener = new SharedPreferences.OnSharedPreferenceChangeListener() { 
     @Override 
     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 
      Preferences.sync(getPreferenceManager(), key); 
      if (key.equals(getString(R.string.pref_theme))) { 
       finish(); 
       final Intent intent = IntentCompat.makeMainActivity(new ComponentName(
         SettingsActivity.this, MainActivity.class)); 
       intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK); 
       startActivity(intent); 
      } 
     } 
    }; 
} 

はデモの完全な例を参照してください。私は最終的に以下の方法を使用してそれを行っている

0

すべてのリソースがRクラスのフィールドであることを考えれば、リフレクションを使用してそれらを探すことができます。これはコストがかかりますが、int値を取得しようとしているので、取得した後に格納してパフォーマンスの低下を避けることができます。そして、リソースを使用するメソッドは任意のintをとるので、int変数をプレースホルダとして使用し、目的の色を配置することができます。任意のリソースを取得するための

String awesomeColor = "blue"; 
int color = getResourceId(R.color, awesomeColor, false); 
if(blue>0) ((TextView) findViewById(R.id.myItem)).setTextColor(color); 

機能:ここ

public static int getResourceId(Class rClass, String resourceText, boolean showExceptions){ 

     String key = rClass.getName()+"-"+resourceText; 

     if(FailedResourceMap.containsKey(key)) return 0; 
     if(ResourceMap.containsKey(key)) return ResourceMap.get(rClass.getName()+"-"+resourceText); 

     try { 

      String originalText = resourceText; 
      if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.GINGERBREAD){ 
       resourceText = ValidationFunctions.normalizeText(resourceText); 
      } 
      resourceText = resourceText.replace("?", "").replace(" ", " ").replace(" ", "_").replace("(", "").replace(")", ""); 

      int resource = rClass.getDeclaredField(resourceText).getInt(null); 
      ResourceMap.put(rClass.getName()+"-"+originalText, resource); 

      return resource; 
     } catch (IllegalAccessException | NullPointerException e) { 
      FailedResourceMap.put(key, 0); 
      if(showExceptions) e.printStackTrace(); 
     } catch (NoSuchFieldException e) { 
      FailedResourceMap.put(key, 0); 
      if(showExceptions) e.printStackTrace(); 
     } 

     return 0; 
    } 

作業バージョン:https://github.com/fcopardo/AndroidFunctions/blob/master/src/main/java/com/grizzly/functions/TextFunctions.java

この治療法は、任意のアンドロイドのリソースに対して有効です。中間変数を使用する代わりに、テーマをこのように設定することもできます。

public static void onActivityCreateSetTheme(Activity activity) 
    { 
    int theme = getResourceId(R.style, activity.getClass().getSimpleName(), false); 
    if(theme > 0) activity.setTheme(theme); 
    } 
関連する問題