प्रोग्रामर छवियों को प्रोग्रामेटिक रूप से बदलें


116

मेरे पास एक ImageView है जिसमें एक चयन करने योग्य चित्र संसाधन है। मैं कैसे प्रोग्रामर को चयनकर्ता तक पहुँचा सकता हूं और हाइलाइटेड और गैर-हाइलाइट किए गए राज्य की छवियों को बदल सकता हूं?

यहाँ चयनकर्ता का एक कोड है:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/iconSelector">
  <!-- pressed -->
  <item android:state_pressed="true" android:drawable="@drawable/btn_icon_hl" />
  <!-- focused -->
  <item android:state_focused="true" android:drawable="@drawable/btn_icon_hl" />
  <!-- default -->
  <item android:drawable="@drawable/btn_icon" />
</selector>

मैं प्रतिस्थापित करना चाहता हूं btn_icon_hlऔर btn_iconअन्य छवियों के साथ।


यह आसान नहीं होगा दो चयनकर्ताओं और उन्हें स्वैप?
bigstones

2
समस्या यह है कि क्या आप सैकड़ों xml फ़ाइलों के साथ समाप्त हो सकते हैं।
एमिल

जवाबों:


244

जहां तक ​​मैं खोजने में सक्षम रहा हूं (मैंने खुद भी कुछ ऐसा ही करने की कोशिश की है), स्टेटलिस्टड्रैबल के पहले से परिभाषित होने के बाद एक भी राज्य को संशोधित करने का कोई तरीका नहीं है। हालाँकि, आप एक नया कोड के माध्यम से परिभाषित कर सकते हैं:

StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed},
    getResources().getDrawable(R.drawable.pressed));
states.addState(new int[] {android.R.attr.state_focused},
    getResources().getDrawable(R.drawable.focused));
states.addState(new int[] { },
    getResources().getDrawable(R.drawable.normal));
imageView.setImageDrawable(states);

और आप बस उनमें से दो को हाथ में रख सकते हैं, या एक अलग बना सकते हैं जैसे आपको इसकी आवश्यकता है।


1
मैं इसे छवि दृश्य में शामिल नहीं कर पाया। setState इस पर उपलब्ध नहीं है।
dropsOfJupiter

2
वास्तव में मैंने इसे पाया, इसका सेटइमेजड्राएबल () बहुत बहुत धन्यवाद, इसने काम किया और मुझे लगभग 40 xml फाइलें बचाईं!
dropsOfJupiter

2
इसलिए मेरे पास इससे संबंधित एक और नोट है। मुझे उम्मीद थी कि आप जवाब दे सकते हैं। मेरे पास यह चयनकर्ता ImageView पर सेट है जो कस्टम नियंत्रण के अंदर है। कस्टम नियंत्रण में पृष्ठभूमि के रूप में चयनकर्ता भी होता है। इसलिए संपूर्ण नियंत्रण का चयनकर्ता काम करता है, जबकि ImageView चयनकर्ता नहीं करता है। क्या कुछ है जो मैं गलत कर रहा हूँ? क्या कोई क्रम है?
dropsOfJupiter

1
आपका स्वागत है! हाँ, मुझे नहीं पता कि मैंने सेटस्ट्रेट क्यों रखा है, सेटआईमैजेजेबल होना चाहिए, आप सही हैं। आपके अन्य प्रश्न के अनुसार, मैं आपके कस्टम नियंत्रण और उसके चयनकर्ता के लिए कोड के साथ एक नया प्रश्न पोस्ट करने का सुझाव दूंगा, मुझे उस पर उत्तर पर यकीन नहीं है।
केविन कोप्पॉक

3
मैं उसी कोड का उपयोग कर रहा हूं। हमेशा वह छवि जो मैंने ----> नए int में निर्दिष्ट की है [] {} स्थिति बनी हुई है। मैं कहाँ गलत था ??
KK_07k11A0585

6

मुझे भी यही समस्या थी और इसे सुलझाने के लिए एक कदम और आगे बढ़ा। केवल समस्या यह है कि आप XSt में NavStateListDrawable को निर्दिष्ट नहीं कर सकते हैं, इसलिए आपको कोड के माध्यम से अपने UI तत्व की पृष्ठभूमि सेट करनी होगी। OnStateChange विधि को तब यह सुनिश्चित करने के लिए ओवरराइड किया जाना चाहिए कि हर बार मुख्य ड्रॉबल का स्तर बदल जाता है, कि आप बच्चे के स्तर की सूची के स्तर को भी अपडेट करते हैं।

NavStateListDrawable का निर्माण करते समय आपको उस आइकन के स्तर से गुजरना होगा जिसे आप प्रदर्शित करना चाहते हैं।

public class NavStateListDrawable extends StateListDrawable {

    private int level;

    public NavStateListDrawable(Context context, int level) {

        this.level = level;
        //int stateChecked = android.R.attr.state_checked;
        int stateFocused = android.R.attr.state_focused;
        int statePressed = android.R.attr.state_pressed;
        int stateSelected = android.R.attr.state_selected;

        addState(new int[]{ stateSelected      }, context.getResources().getDrawable(R.drawable.nav_btn_pressed));
        addState(new int[]{ statePressed      }, context.getResources().getDrawable(R.drawable.nav_btn_selected));
        addState(new int[]{ stateFocused      }, context.getResources().getDrawable(R.drawable.nav_btn_focused));

        addState(new int[]{-stateFocused, -statePressed, -stateSelected}, context.getResources().getDrawable(R.drawable.nav_btn_default));


    }

    @Override
    protected boolean onStateChange(int[] stateSet) {

        boolean nowstate = super.onStateChange(stateSet);

        try{
            LayerDrawable defaultDrawable = (LayerDrawable)this.getCurrent();


            LevelListDrawable bar2 =  (LevelListDrawable)defaultDrawable.findDrawableByLayerId(R.id.nav_icons);
            bar2.setLevel(level);
        }catch(Exception exception)
        {

        }

        return nowstate;
    }
}

विभिन्न नेविगेशन बटन ड्रॉबल स्टेट्स के सभी के लिए मेरे पास कुछ इस तरह है।

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

   <item android:drawable="@drawable/top_bar_default" >

   </item>

    <item android:id="@+id/nav_icons" android:bottom="0dip">
        <level-list xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:maxLevel="0" >
                <bitmap
                    android:src="@drawable/top_bar_icon_back"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="1" >
                <bitmap
                    android:src="@drawable/top_bar_icon_nav"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="2" >
                <bitmap
                    android:src="@drawable/top_bar_icon_settings"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="3" >
                <bitmap
                    android:src="@drawable/top_bar_icon_search"
                    android:gravity="center" />
            </item>
        </level-list>

    </item>

</layer-list>

मैं इसे एक प्रश्न और उत्तर के रूप में पोस्ट करने जा रहा था, लेकिन जैसा कि आपने बहुत प्रश्न पूछा है, यह देखते हुए कि आप यहां जाते हैं। ध्यान दें, यह आपको बहुत सारे xml फ़ाइल परिभाषाओं का एक नरक बचाता है। मैं नीचे के बारे में 50-100 xml परिभाषा के बारे में 4 से नीचे चला गया!।


Navstatelistdrawable कोड प्रभावी रूप से चयनकर्ता xml को निरर्थक बनाता है।
एमिल

हाय एमिली, क्या ऐसी संभावना है कि बटन पृष्ठभूमि के रूप में किसी भी कारण से पहली बार दिखाई दे। वर्तमान में मुझे वह समस्या मिल रही है जहां मुझे पृष्ठभूमि के क्षेत्र को दिखाने के लिए, या स्विच आउट करने और गतिविधि पर वापस जाने के लिए बटन के क्षेत्र को छूने की आवश्यकता है। (यह केवल एक hdpi स्क्रीन पर होता है, लेकिन मेरे mdpi पर ठीक काम करता है)। मेरा मानना ​​है कि दूसरों को भी यह समस्या हो सकती है। क्या आपका कोड सभी स्क्रीन घनत्व के लिए परीक्षण किया गया है?
ryvianstyron

हाय, नहीं, यह एक मेला के समय लिखा गया था और उस समय केवल एक उपकरण के लिए था। मुझे यकीन नहीं है कि मैं किस तरह के मुद्दे को उठा सकता हूं, क्योंकि जहां तक ​​मुझे पता है कि मल्टीपल स्क्रीन डेंसिटीज और लेआउट्स में समस्या नहीं होनी चाहिए।
एमिल

धन्यवाद मुझे पता नहीं है कि मैं क्या गलत कर रहा था, लेकिन अंत में मेरे पास बस निम्नलिखित थे: buttonStates = new StateListDrawable (); buttonStates.addState (नया int [] {StatePressed}, ApplicationConstants.moduleImageLoader.findImageByName (drawable_pressed)); buttonStates.addState (नया int [] {- ​​StateFocused, -statePressed, -stateSelected}, ApplicationConstants.moduleImageLoader.findImageBnName (drawable_normal));
२०:०२ पर ryvianstyron

1
यह पहली जगह है जहां मैं देखता हूं कि झूठे के लिए निर्धारित राज्यों के लिए नकारात्मक मूल्यों का उपयोग किया जाना है। प्रलेखन इसके बारे में बहुत स्पष्ट नहीं है। पारितोषिक के लिए धन्यवाद!
इकोन्हा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.