2017-03-21 20 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. निकालने एक विषय से एक शैली के लिए एक रास्ता के लिए देख रहे हैं,
  2. से एक मूल्य (पाठ का रंग) निकालने शैली कहा।

चलो इसे प्राप्त करें।

// 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 के माध्यम से थीम आईडी पास करने के बारे में क्या?

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

और फिर onCreate में:

// 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

इस तथ्य को देखते हुए कि हर संसाधन आर कक्षा में एक क्षेत्र है, आप प्रतिबिंब का उपयोग करके उनकी तलाश कर सकते हैं। यह महंगा है, लेकिन चूंकि आप एक 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); 
    } 
संबंधित मुद्दे