@ (टेड होप) द्वारा इंगित किया गया समाधान काम करता है, लेकिन इसमें थोड़ा सुधार करने की आवश्यकता है: चयनकर्ता में, आइटम राज्यों को एक "ऐप:" उपसर्ग की आवश्यकता होती है, अन्यथा फ्लोटर नामस्थान को सही ढंग से पहचान नहीं पाएगा, और चुपचाप विफल हो जाएगा; कम से कम मेरे साथ ऐसा ही होता है।
मुझे कुछ और विवरणों के साथ संपूर्ण समाधान की रिपोर्ट करने की अनुमति दें:
सबसे पहले, फ़ाइल "Res / मान / attrs.xml" बनाएं:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="food">
<attr name="state_fried" format="boolean" />
<attr name="state_baked" format="boolean" />
</declare-styleable>
</resources>
फिर अपने कस्टम वर्ग को परिभाषित करें। उदाहरण के लिए, यह एक वर्ग "फूडबटन" हो सकता है, जो "बटन" से लिया गया है। आपको एक कंस्ट्रक्टर लागू करना होगा; इसे लागू करें, जो कि इनफ्लोटर द्वारा उपयोग किया जाने वाला लगता है:
public FoodButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
व्युत्पन्न वर्ग के शीर्ष पर:
private static final int[] STATE_FRIED = {R.attr.state_fried};
private static final int[] STATE_BAKED = {R.attr.state_baked};
इसके अलावा, आपके राज्य चर:
private boolean mIsFried = false;
private boolean mIsBaked = false;
और बसने वालों की एक जोड़ी:
public void setFried(boolean isFried) {mIsFried = isFried;}
public void setBaked(boolean isBaked) {mIsBaked = isBaked;}
फिर कार्य को ओवरराइड करें "onCreateDrawableState":
@Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 2);
if (mIsFried) {
mergeDrawableStates(drawableState, STATE_FRIED);
}
if (mIsBaked) {
mergeDrawableStates(drawableState, STATE_BAKED);
}
return drawableState;
}
अंत में, इस पहेली का सबसे नाजुक टुकड़ा; चयनकर्ता StateListDrawable को परिभाषित करता है जिसे आप अपने विजेट के लिए पृष्ठभूमि के रूप में उपयोग करेंगे। यह फ़ाइल "res / drawable / food_button.xml" है:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.mydomain.mypackage">
<item
app:state_baked="true"
app:state_fried="false"
android:drawable="@drawable/item_baked" />
<item
app:state_baked="false"
app:state_fried="true"
android:drawable="@drawable/item_fried" />
<item
app:state_baked="true"
app:state_fried="true"
android:drawable="@drawable/item_overcooked" />
<item
app:state_baked="false"
app:state_fried="false"
android:drawable="@drawable/item_raw" />
</selector>
"ऐप:" उपसर्ग को नोटिस करें, जबकि मानक एंड्रॉइड राज्यों के साथ आपने उपसर्ग "एंड्रॉइड:" का उपयोग किया होगा। एक्सएमएल नेमस्पेस एक सही व्याख्या के लिए महत्वपूर्ण है जो कि इनफ्लोटर द्वारा सही व्याख्या करता है और उस परियोजना के प्रकार पर निर्भर करता है जिसमें आप विशेषताएँ जोड़ रहे हैं। यदि यह एक अनुप्रयोग है, तो com.mydomain.mypackage को अपने आवेदन के वास्तविक पैकेज नाम (आवेदन नाम को छोड़कर) के साथ बदलें । यदि यह एक पुस्तकालय है, तो आपको "http://schemas.android.com/apk/res-auto" (और उपकरण R17 या बाद का उपयोग करना होगा) का उपयोग करना होगा या आपको रनटाइम त्रुटियाँ मिलेंगी।
नोटों की एक जोड़ी:
ऐसा लगता है कि आपको "रिफ्रेशडेबलटेस्ट" फ़ंक्शन को कॉल करने की आवश्यकता नहीं है, कम से कम समाधान मेरे मामले में अच्छी तरह से काम करता है
लेआउट xml फ़ाइल में अपने कस्टम वर्ग का उपयोग करने के लिए, आपको पूरी तरह से योग्य नाम (जैसे com.mydomain.mypackage.FoodButton) निर्दिष्ट करना होगा
आप और अधिक जटिल राज्य संयोजनों का प्रतिनिधित्व करने के लिए कस्टम राज्यों के साथ मिलाने के लिए मानक राज्यों (जैसे कि android: दबाया, Android: सक्षम, Android: चयनित) को मिला सकते हैं