जब यह एक संदर्भ (थीम) हो, तो रंग मूल्य को प्रोग्रामेटिक रूप से प्राप्त करें


116

इस पर विचार करो:

styles.xml

<style name="BlueTheme" parent="@android:style/Theme.Black.NoTitleBar">
    <item name="theme_color">@color/theme_color_blue</item>
</style>

attrs.xml

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

color.xml

<color name="theme_color_blue">#ff0071d3</color>

तो विषय रंग विषय द्वारा संदर्भित है। मैं प्रोग्राम_कोलर (संदर्भ) प्रोग्रामेटिक रूप से कैसे प्राप्त कर सकता हूं? आम तौर पर मैं getResources().getColor()इस मामले में उपयोग नहीं करूंगा क्योंकि यह संदर्भित है!

जवाबों:


255

यह काम करना चाहिए:

TypedValue typedValue = new TypedValue();
Theme theme = context.getTheme();
theme.resolveAttribute(R.attr.theme_color, typedValue, true);
@ColorInt int color = typedValue.data;

इस कोड को कॉल करने से पहले विषय को अपनी गतिविधि पर लागू करना सुनिश्चित करें। या तो उपयोग करें:

android:theme="@style/Theme.BlueTheme"

आपके मैनिफ़ेस्ट या कॉल में (कॉल करने से पहले setContentView(int)):

setTheme(R.style.Theme_BlueTheme)

में है onCreate()

मैंने आपके मूल्यों के साथ इसका परीक्षण किया है और इसने पूरी तरह से काम किया है।


धन्यवाद, मैं आपके समाधान की कोशिश नहीं कर सकता क्योंकि अभी तक मुझे एक त्रुटि मिली है: stackoverflow.com/questions/17278244/… हो सकता है कि आपको इसमें अनुभव हो ...
Seraphim's

5
वैसे भी, आपके समाधान से मुझे 0 मान रंग मिलता है (TypedValue {t = 0x0 / d = 0x0}) ... मैं घोषित-शैली का उपयोग नहीं करता हूं, बस रंग का संदर्भ है
सेराफिम का

क्या आप विषय को गतिविधि पर लागू करते हैं?
इमानुएल मोएक्लिन

5
यदि आप गतिविधि के लिए विषय को लागू नहीं करना चाहते हैं, तो आप ContextThemeWrapperथीम आईडी का उपयोग करके बना सकते हैं और फिर उस विषय को पुनः प्राप्त कर सकते हैं ।
टेड हॉप

1
यह विधि एंड्रॉइड X (सामग्री डिजाइनिंग) में काम करती है
BlackBlind

43

स्वीकृत उत्तर में जोड़ने के लिए, यदि आप कोटलिन का उपयोग कर रहे हैं।

@ColorInt
fun Context.getColorFromAttr(
    @AttrRes attrColor: Int,
    typedValue: TypedValue = TypedValue(),
    resolveRefs: Boolean = true
): Int {
    theme.resolveAttribute(attrColor, typedValue, resolveRefs)
    return typedValue.data
}

और फिर अपनी गतिविधि में आप कर सकते हैं

textView.setTextColor(getColorFromAttr(R.attr.color))


2
oook, "एकीकरण" के लिए धन्यवाद। मैं कोटलिन का उपयोग नहीं कर रहा हूं, लेकिन यह दिलचस्प है।
सेराफिम का

5
वैसे यह टाइप्डवैल्यू को बाहरी दुनिया के लिए दृश्यमान बनाता है। और रंगों के लिए आप हमेशा @ColorInt fun Context.getThemeColor(@AttrRes attribute: Int) = TypedValue().let { theme.resolveAttribute(attribute, it, true); it.data }
संदर्भात्मक

1
उपयोग इस तरह होगा:val errorColor = context.getThemeColor(R.attr.colorError)
milosmns

अधिक सार्वभौमिक तरीका, जो के लिए डिफ़ॉल्ट मान भी प्राप्त करता है ColorStateList: @ColorInt fun Context.getThemeColor(@AttrRes attribute: Int) = obtainStyledAttributes(intArrayOf(attribute)).use { it.getColor(0, Color.MAGENTA) }( निक बुचर से )
gmk57

अंतिम तरीका, जो पूरे को पुनः प्राप्त करता है ColorStateList, भले ही वह किसी अन्य विषय विशेषताओं का संदर्भ देता हो: fun Context.getThemeColor(@AttrRes attribute: Int): ColorStateList = TypedValue().let { theme.resolveAttribute(attribute, it, true); AppCompatResources.getColorStateList(this, it.resourceId) }(एकल रंग भी लपेटा जाएगा ColorStateList)।
gmk57

24

यह मेरे लिए काम किया:

int[] attrs = {R.attr.my_attribute};
TypedArray ta = context.obtainStyledAttributes(attrs);
int color = ta.getResourceId(0, android.R.color.black);
ta.recycle();

यदि आप इससे बाहर निकलना चाहते हैं:

Integer.toHexString(color)

यह एक ColorRes, एक ColorInt नहीं लौटना चाहिए।
मिहा_एक्स ६४

मैं getColorResource (रंग) के साथ इसका उपयोग कर रहा हूं और रीसायकल को नहीं बुला रहा हूं।
ज़ीक ऐरन

2

यदि आप कई रंगों को प्राप्त करना चाहते हैं, जिनका आप उपयोग कर सकते हैं:

int[] attrs = {R.attr.customAttr, android.R.attr.textColorSecondary, 
        android.R.attr.textColorPrimaryInverse};
Resources.Theme theme = context.getTheme();
TypedArray ta = theme.obtainStyledAttributes(attrs);

int[] colors = new int[attrs.length];
for (int i = 0; i < attrs.length; i++) {
    colors[i] = ta.getColor(i, 0);
}

ta.recycle();

2

इसे अपने build.gradle (ऐप) में जोड़ें:

implementation 'androidx.core:core-ktx:1.1.0'

और इस एक्सटेंशन फंक्शन को अपने कोड में कहीं जोड़ें:

@ColorInt
@SuppressLint("Recycle")
fun Context.themeColor(
    @AttrRes themeAttrId: Int
): Int {
    return obtainStyledAttributes(
        intArrayOf(themeAttrId)
    ).use {
        it.getColor(0, Color.MAGENTA)
    }
}

0

यहां एक संक्षिप्त जावा उपयोगिता पद्धति है जो कई विशेषताओं को लेती है और एक पूर्णांक के रंग को लौटाती है। :)

/**
 * @param context    Pass the activity context, not the application context
 * @param attrFields The attribute references to be resolved
 * @return int array of color values
 */
@ColorInt
static int[] getColorsFromAttrs(Context context, @AttrRes int... attrFields) {
    int length = attrFields.length;
    Resources.Theme theme = context.getTheme();
    TypedValue typedValue = new TypedValue();

    @ColorInt int[] colorValues = new int[length];

    for (int i = 0; i < length; ++i) {
        @AttrRes int attr = attrFields[i];
        theme.resolveAttribute(attr, typedValue, true);
        colorValues[i] = typedValue.data;
    }

    return colorValues;
}

जावा इसके लिए कोटलिन से बेहतर है?
22 अगस्त को इगोरगानपोलस्की

@IgorGanapolsky ओह, मैं ईमानदारी से नहीं जानता। मैंने अपना कोड साझा किया क्योंकि मुझे पता था कि यह किसी के लिए काम आएगा! मैं कोटलिन को नहीं जानता और मैं मानता हूं कि कोटलिन इसे किसी भी बेहतर प्रदर्शन नहीं करेगा, शायद कोड की कम लाइनें! : पी
वरुण

-1

जो एक drawable आप का उपयोग करना चाहिए करने के लिए संदर्भ के लिए देख रहे हैं उन लोगों के लिए falseमेंresolveRefs

theme.resolveAttribute(R.attr.some_drawable, typedValue, **false**);


चर के संदर्भ में क्या लिखें?
BENN1TH

परिवर्तनशील विषय को व्हाट्सएप करें।
BENN1TH
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.