मैं प्रोग्रामेटिक रूप से ColorStateList कैसे बनाऊँ?


158

मैं ColorStateListइसका उपयोग करके प्रोग्राम बनाने की कोशिश कर रहा हूं :

ColorStateList stateList = new ColorStateList(states, colors); 

लेकिन मुझे यकीन नहीं है कि दो पैरामीटर क्या हैं।

प्रलेखन के अनुसार:

public ColorStateList (int[][] states, int[] colors) 

एपीआई स्तर 1 में जोड़ा गया

एक ColorStateList बनाता है जो राज्यों से रंगों में निर्दिष्ट मैपिंग लौटाता है।

क्या कोई कृपया मुझे समझा सकता है कि इसे कैसे बनाया जाए?

राज्यों के लिए द्वि-आयामी सरणी का अर्थ क्या है?

जवाबों:


343

उपलब्ध राज्यों की सूची के लिए http://developer.android.com/reference/android/R.attr.html#state_above_anchor देखें ।

यदि आप विकलांग, अनियंत्रित, अनियंत्रित राज्यों आदि के लिए रंग सेट करना चाहते हैं, तो बस राज्यों को नकारें:

int[][] states = new int[][] {
    new int[] { android.R.attr.state_enabled}, // enabled
    new int[] {-android.R.attr.state_enabled}, // disabled
    new int[] {-android.R.attr.state_checked}, // unchecked
    new int[] { android.R.attr.state_pressed}  // pressed
};

int[] colors = new int[] {
    Color.BLACK,
    Color.RED,
    Color.GREEN,
    Color.BLUE
};

ColorStateList myList = new ColorStateList(states, colors);

45
"विपरीत" राज्यों के बारे में जानकारी के लिए धन्यवाद!
बीवीबी

यह डिजाइन लाइब्रेरी से फैब का रंग बदलने के लिए इस्तेमाल किया जा सकता है।
टेपिरबॉय

5
चेतावनी: रोजर एलियन के उत्तर (और इसकी पहली टिप्पणी) को यह समझने के लिए देखें कि यहां राज्यों का क्रम खराब है: क्योंकि "सक्षम" पहले है, यह अन्य राज्यों को ओवरराइड करेगा जो आमतौर पर एक बटन सक्षम होने पर होते हैं। अंतिम "सक्षम" लगाने के लिए बेहतर है। (या "सक्षम" के बजाय, एक खाली / डिफ़ॉल्ट आइटम अंतिम है।)
टूलमेकर

2
एक बटन है कि राज्य को बनाए रखने नहीं करता है (नहीं एक टॉगल / चेकबॉक्स) हो सकता है के लिए राज्यों का एक बुनियादी सूची {pressed}, {focused}, {-enabled}, {}। यह टॉगल एक हो सकता है के लिए {checked, pressed}, {pressed}, {checked, focused}, {focused}, {checked}, {-enabled}, {}। या फिर एक टॉगल कि ध्यान न दी ध्यान केंद्रित: {checked, pressed}, {pressed}, {checked}, {-enabled}, {}
टूलमेकरसेव

मामले में अगर कोई उन समाधानों में से किसी को भी आजमाएगा, तो राज्यों को उस चयनकर्ता पर ध्यान दें जैसे चयनकर्ता। Xml!
एंटोन माकोव

75

पहला आयाम राज्य सेट की एक सरणी है, दूसरा ist राज्य सेट ही है। रंग सरणी प्रत्येक मिलान स्थिति सेट के लिए रंगों को सूचीबद्ध करती है, इसलिए रंग सरणी की लंबाई को राज्यों के सरणी के पहले आयाम से मेल खाना पड़ता है (या यह तब दुर्घटनाग्रस्त हो जाएगा जब राज्य "उपयोग किया जाता है")। यहाँ और उदाहरण:

ColorStateList myColorStateList = new ColorStateList(
                        new int[][]{
                                new int[]{android.R.attr.state_pressed}, //1
                                new int[]{android.R.attr.state_focused}, //2
                                new int[]{android.R.attr.state_focused, android.R.attr.state_pressed} //3
                        },
                        new int[] {
                            Color.RED, //1
                            Color.GREEN, //2
                            Color.BLUE //3
                        }
                    );

उम्मीद है की यह मदद करेगा।

EDIT उदाहरण: एक xml रंग राज्य सूची जैसे:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/white"/>
    <item android:color="@color/black"/>
</selector>

इस तरह दिखेगा

ColorStateList myColorStateList = new ColorStateList(
        new int[][]{
                new int[]{android.R.attr.state_pressed},
                new int[]{}
        },
        new int[] {
                context.getResources().getColor(R.color.white),
                context.getResources().getColor(R.color.black)
        }
);

क्या आप बता सकते हैं कि नीचे दिए गए xml का प्रतिनिधित्व कैसे करें "<selector xmlns: android =" schemas.android.com/apk/res/android "> <आइटम Android: state_pressed =" true "android: color =" @ color / white / / > <आइटम Android: colorstatelist का उपयोग करके रंग = "@ रंग / काला" /> </ चयनकर्ता>।
सतीश

@ सतीशकुमार मेरे संपादन की जाँच करें, मैंने इसका परीक्षण नहीं किया है।
सू-औ ह्वांग

3
वर्थ ने कहा कि एक झूठी स्थिति को निर्दिष्ट करने के लिए, आप इसके मूल्य को नकार सकते हैं, इसलिए यदि आप किसी रंग को निर्दिष्ट करना चाहते हैं जब उसे दबाया नहीं जाता है, तो आपको उपयोग करना चाहिए: नया int [] {- ​​android.R.attr.state_pressed}
tinsukE

1
@TinsukE ने जो कहा, उस पर जोड़ने के लिए: हालाँकि, गलती से सूची में बाद में किसी आइटम को दबाने से बचने के लिए, अधिकांश राज्यों के लिए यह एक नकार लगाने के लिए समझ में नहीं आएगा - बजाय एक डिफ़ॉल्ट (खाली) आइटम के साथ सभी "अन्य" संभावनाओं को संभालना new int[]{}अंतिम - जैसा कि इस उत्तर के अंतिम कोड ब्लॉक में दिखाया गया है। एकमात्र नकारात्मक मूल्य जो मैं आमतौर पर उपयोग करता हूं, वह "-एनेबल" है। एक अन्य उदाहरण है, अगर आप तीन अलग अलग रंग हैं: "ध्यान केंद्रित + दबाया", "ध्यान केंद्रित + दबाया नहीं", "दबाया + ध्यान केंद्रित नहीं", तो आप बस डाल सकते हैं {focused, pressed}, {focused}, {pressed}। पहले "सही" एक का उपयोग किया जाएगा।
टूलमेकरसेव

2
... गलती आप कर सकते हैं की तरह एक श्रृंखला है {pressed}, {-pressed}, {focused}, {-focused}। समस्या यह है कि {pressed}और {-pressed}सभी संभावनाओं को कवर (बटन दबाया जाता है या तो या दबाया नहीं), इसलिए कोई बाद में सूचीबद्ध रंग कभी इस्तेमाल किया जाएगा।!
टूलमेकरसेव

64

कभी-कभी यह पर्याप्त होगा:

int colorInt = getResources().getColor(R.color.ColorVerificaLunes);
ColorStateList csl = ColorStateList.valueOf(colorInt);

20

दुर्भाग्य से कोई भी समाधान मेरे लिए काम नहीं करता है।

  1. यदि आप पहली बार दबाए गए राज्य को सेट नहीं करते हैं तो यह पता नहीं लगाएगा।
  2. यदि आप इसे सेट करते हैं, तो आपको डिफ़ॉल्ट रंग जोड़ने के लिए खाली स्थिति को परिभाषित करने की आवश्यकता है
ColorStateList themeColorStateList = new ColorStateList(
        new int[][]{
                new int[]{android.R.attr.state_pressed},
                new int[]{android.R.attr.state_enabled},
                new int[]{android.R.attr.state_focused, android.R.attr.state_pressed},
                new int[]{-android.R.attr.state_enabled},
                new int[]{} // this should be empty to make default color as we want
        },
        new int[]{
                pressedFontColor,
                defaultFontColor,
                pressedFontColor,
                disabledFontColor,
                defaultFontColor
        }
);

यह स्रोत कोड से निर्माता है:

/**
 * Creates a ColorStateList that returns the specified mapping from
 * states to colors.
 */
public ColorStateList(int[][] states, int[] colors) {
    mStateSpecs = states;
    mColors = colors;

    if (states.length > 0) {
        mDefaultColor = colors[0];

        for (int i = 0; i < states.length; i++) {
            if (states[i].length == 0) {
                mDefaultColor = colors[i];
            }
        }
    }
}

5
सिद्दत के रूप में: आपको इसे वैसा ही मानना ​​होगा, जैसा आप एक इफिस-इफिस को मानते हैं। यह पहली अवस्था का चयन करता है जो सत्य है। इसलिए, यदि आपके पास पहले राज्य के रूप में State_enabled है, तो इसे State_pressed से पहले चुना जाएगा - जब तक कि दृश्य अक्षम न हो।
सिंह राशि

एफडब्ल्यूआईडब्ल्यू, जब से आपको अंतिम तत्व मिला है, मुझे नहीं लगता कि पहला "सक्षम" तत्व आपको बिल्कुल अच्छा कर रहा है। इसे पूरी तरह से क्यों नहीं हटाया गया?
टूलमेकरसेव

18

ColorListकोटलिन में प्रोग्राम बनाने के तरीके का एक उदाहरण इस प्रकार है :

val colorList = ColorStateList(
        arrayOf(
                intArrayOf(-android.R.attr.state_enabled),  // Disabled
                intArrayOf(android.R.attr.state_enabled)    // Enabled
        ),
        intArrayOf(
                Color.BLACK,     // The color for the Disabled state
                Color.RED        // The color for the Enabled state
        )
)

इसके अलावा, एक कोटलिन सहायक समारोह के लिए नीचे मेरा जवाब देखें
इस्कॉलेक

7

जोनाथन एलिस द्वारा जवाब में उछलते हुए , कोटलिन में आप कोड को थोड़ा और अधिक मुहावरेदार और पढ़ने में आसान बनाने के लिए एक सहायक फ़ंक्शन को परिभाषित कर सकते हैं, इसलिए आप इसके बजाय यह लिख सकते हैं:

val colorList = colorStateListOf(
    intArrayOf(-android.R.attr.state_enabled) to Color.BLACK,
    intArrayOf(android.R.attr.state_enabled) to Color.RED
)

colorStateListOf इस तरह लागू किया जा सकता है:

fun colorStateListOf(vararg mapping: Pair<IntArray, Int>): ColorStateList {
    val (states, colors) = mapping.unzip()
    return ColorStateList(states.toTypedArray(), colors.toIntArray())
}

मेरे पास भी है:

fun colorStateListOf(@ColorInt color: Int): ColorStateList {
    return ColorStateList.valueOf(color)
}

ताकि मैं एक ही फ़ंक्शन नाम को कॉल कर सकूं, चाहे वह चयनकर्ता या एकल रंग हो।


3

बनाने के लिए मेरा बिल्डर वर्ग ColorStateList

private class ColorStateListBuilder {
    List<Integer> colors = new ArrayList<>();
    List<int[]> states = new ArrayList<>();

    public ColorStateListBuilder addState(int[] state, int color) {
        states.add(state);
        colors.add(color);
        return this;
    }

    public ColorStateList build() {
        return new ColorStateList(convertToTwoDimensionalIntArray(states),
                convertToIntArray(colors));
    }

    private int[][] convertToTwoDimensionalIntArray(List<int[]> integers) {
        int[][] result = new int[integers.size()][1];
        Iterator<int[]> iterator = integers.iterator();
        for (int i = 0; iterator.hasNext(); i++) {
            result[i] = iterator.next();
        }
        return result;
    }

    private int[] convertToIntArray(List<Integer> integers) {
        int[] result = new int[integers.size()];
        Iterator<Integer> iterator = integers.iterator();
        for (int i = 0; iterator.hasNext(); i++) {
            result[i] = iterator.next();
        }
        return result;
    }
}

उदाहरण का उपयोग करना

ColorStateListBuilder builder = new ColorStateListBuilder();
builder.addState(new int[] { android.R.attr.state_pressed }, ContextCompat.getColor(this, colorRes))
       .addState(new int[] { android.R.attr.state_selected }, Color.GREEN)
       .addState(..., some color);

if(// some condition){
      builder.addState(..., some color);
}
builder.addState(new int[] {}, colorNormal); // must add default state at last of all state

ColorStateList stateList = builder.build(); // ColorStateList created here

// textView.setTextColor(stateList);

2

यदि आप Colors.xml संसाधन का उपयोग करते हैं

int[] colors = new int[] {
                getResources().getColor(R.color.ColorVerificaLunes),
                getResources().getColor(R.color.ColorVerificaMartes),
                getResources().getColor(R.color.ColorVerificaMiercoles),
                getResources().getColor(R.color.ColorVerificaJueves),
                getResources().getColor(R.color.ColorVerificaViernes)

        };

ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{colors[0]}); 

    example.setBackgroundTintList(csl);

2
के रूप getResources()में पदावनत किया जाता है, यह अब ContextCompat.getColor(this,R.color.colorname);या ContextCompat.getColor(getActivity(),R.color.colorname);एक Fragment में उपयोग के लिए है
ibusb

अन्य पाठकों के लिए स्पष्ट करने के लिए, new int[0](पहली पैरामीटर्स सूची में एक तत्व के रूप में) एक शून्य-लंबाई सरणी है, और डिफ़ॉल्ट रंग सेट करने का प्रतिनिधित्व करता है। यहां यह एकमात्र तत्व है, जिसका अर्थ है कि बटन के सभी राज्यों पर टिंट लागू किया जाता है । यह new int[]{}रोजर एलियन के जवाब में देखने के बराबर है ।
टूलमेकरसेव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.