Android स्पिनर: चयनित आइटम परिवर्तन घटना प्राप्त करें


407

जब आप चयनित आइटम को बदलते हैं तो आप स्पिनर के लिए इवेंट श्रोता कैसे सेट कर सकते हैं?

मूल रूप से मैं जो करने की कोशिश कर रहा हूं वह कुछ इस तरह है:

spinner1.onSelectionChange = handleSelectionChange;

void handleSelectionChange(Object sender){
    //handle event
}

मैंने इन उत्तरों की कोशिश की है, लेकिन कोई भी मददगार नहीं था। एक बार स्पिनर घटक आइटम क्लिक आयोजनों का समर्थन नहीं करता है। स्पिनर प्रलेखन

जवाबों:


812

पिछले उत्तरों में से कुछ सही नहीं हैं। वे अन्य विगेट्स और विचारों के लिए काम करते हैं, लेकिन स्पिनर विजेट के लिए प्रलेखन स्पष्ट रूप से बताता है:

एक स्पिनर आइटम क्लिक आयोजनों का समर्थन नहीं करता है। इस विधि को कॉल करने से अपवाद उत्पन्न होगा।

इसके बजाय OnItemSelectedListener () का बेहतर उपयोग करें :

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
        // your code here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        // your code here
    }

});

यह मेरे लिए काम करता है।

ध्यान दें कि जब दृश्य का निर्माण किया जा रहा हो, तब onItemSelected विधि भी लागू होती है, इसलिए आप इसे onCreate()विधि कॉल के अंदर रखने पर विचार कर सकते हैं ।


47
इसके साथ समस्या यह है कि जब दृश्य का निर्माण किया जा रहा है तो onItemSelected विधि को भी लागू किया जाता है। तो वहाँ जो कोड लिखा होता है वह स्टार्टअप पर भी लागू हो जाता है। क्या केवल उपयोगकर्ता द्वारा आहूत वास्तविक वस्तु चयन होने पर ही कोड को निष्पादित करने का एक तरीका है?
केनेथ्रव

39
वास्तव में उस समस्या को ओवरऑनर्ट विधि में सेटऑन इटम सेलेक्टेड लिस्टनर को सेट करके और ऑनक्रिएट विधि में नहीं करके हल किया जा सकता है। बेवकूफ मुझे ...
केनेथ्रव

16
मैंने श्रोता को onStart पद्धति में रखा है, लेकिन उपयोगकर्ता को कुछ भी देखने को मिलने से पहले ही कॉल किया जाता है, ठीक वैसे ही onCreate है, इसलिए, मेरे मामले में जहां "आगे बढ़ना" बटन का अर्थ अदृश्य है जब तक कि उपयोगकर्ता कुछ का चयन नहीं करता है। बटन प्रारंभिक प्रदर्शन पर दिखाई देता है। क्या आप कह रहे हैं कि आपका अनुभव अलग है? यदि हां, तो आप ऑनस्टार्ट विधि में अलग-अलग क्या कर रहे हैं जो मुझे याद आ रही है?
येवगेनी सिम्किन

7
पहले चयन को रिकॉर्ड करने के लिए अपने अनाम श्रोता के अंदर किसी अन्य फ़ील्ड का उपयोग करें, और यह बताएं कि जब तक चयन का सामना नहीं किया गया है, तब तक कुछ भी न करें? सिर्फ एक विचार।
सैम स्वेनबॉर्गोक्रिस्टिंसेंसन

4
लेकिन क्या होगा अगर उपयोगकर्ता "डिफ़ॉल्ट" आइटम का चयन करता है, शीर्ष पर एक? फिर onItemSelected(...)मारा नहीं जाता। (मुझे पता है क्योंकि मुझे यह कठिन तरीका लगा।)
एंड्रयू व्येल

55
Spinner spnLocale = (Spinner)findViewById(R.id.spnLocale);

spnLocale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { 
        // Your code here
    } 

    public void onNothingSelected(AdapterView<?> adapterView) {
        return;
    } 
}); 

नोट: एक बात याद रखें।

स्पिनर OnItemSelectedListenerघटना को दो बार अंजाम देंगे:

  1. स्पिनर आरंभीकरण
  2. उपयोगकर्ता मैन्युअल रूप से चयनित

ध्वज चर का उपयोग करके उन दोनों को अलग करने का प्रयास करें।


3
मेरा भी दो बार फोन आया! मैं यह नहीं जान सकता कि आप दोनों के बीच अंतर कैसे है?
मैक

18
बस एक वैश्विक बूलियन सेट करें जैसे बूलियन initialDisplay = true; और फिर अपने onSelect में देखें कि क्या यह सच है और यदि यह है, तो आप जो कुछ भी करने जा रहे हैं उसे चयन पर न करें लेकिन झंडे को झूठे पर सेट करें, अगली बार जब इसे बुलाया जाता है (जब उपयोगकर्ता वास्तव में चयन करता है)।
येवगेनी सिम्किन

OnclickListener के निष्पादन के बारे में सबसे अच्छा विवरण।
पंकज कुमार

6
मुझे व्यक्तिगत रूप से यह याद आ रहा है कि कुछ इतना सरल है - ऐसा मौलिक यूआई विजेट - इसे लागू करने के लिए कितना मुश्किल है ... गंभीरता से - एक 'डिफ़ॉल्ट आइटम दिखा रहा है' संपत्ति बनाने के लिए और ऑब्जेक्ट में बूलियन फ्लैग संपत्ति बनाने के लिए कितना मुश्किल होगा वर्ग ही ?? मैं ऑब्जेक्टिव सी का प्रशंसक नहीं हूं, लेकिन मैं कहूंगा कि iOS विजेट का कार्यान्वयन एंड्रॉइड में लगभग 1/10 वां समय लेता है।
बेनेट वॉन बेनेट

4
मैं भी सहमत हूं। स्पिनर एक विजेट है। यह जानने के लिए बहुत कठिन है कि पॉपअप या ड्रॉप कब खुला या बंद है। क्या इसके लिए एक घटना को जोड़ना इतना कठिन था? उपरोक्त समाधान ALMOST आपको बता सकता है कि सूची खुली या बंद है, लेकिन तीन समस्याएं हैं: (1) पहले से चयनित आइटम (और सूची बंद हो जाती है) का चयन करने के लिए कोई घटना नहीं है और (2) गर्भपात के लिए कोई घटना नहीं है (स्पर्श करें) ऑफ-लिस्ट इसे बंद करना) और (3) onNothingSelected मेरे लिए कभी भी आग नहीं लगता।
22

19

आप AdapterView.OnItemSelectedListenerअपनी गतिविधि में कक्षा को लागू कर सकते हैं ।

और उसके बाद नीचे की लाइन का उपयोग करें onCreate()

Spinner spin = (Spinner) findViewById(R.id.spinner);
spin.setOnItemSelectedListener(this);

फिर इन दो तरीकों को ओवरराइड करें:

public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
    selection.setText(items[position]);
}

public void onNothingSelected(AdapterView<?> parent) {
    selection.setText("");
}

16

https://stackoverflow.com/q/1714426/811625

आप OnItemSelectedListener () को एक साधारण जांच के साथ बुलाया जा सकता है: पूर्णांक चर में वर्तमान चयन सूचकांक को स्टोर करें और कुछ भी करने से पहले onItemSelected (..) के भीतर जांचें।

उदाहरण के लिए:

Spinner spnLocale;

spnLocale = (Spinner)findViewById(R.id.spnLocale);

int iCurrentSelection = spnLocale.getSelectedItemPosition();

spnLocale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { 
    if (iCurrentSelection != i){
            // Your code here
    }
    iCurrentSelection = i;
    } 

    public void onNothingSelected(AdapterView<?> adapterView) {
        return;
    } 
}); 

कारण का iCurrentSelectionकाम करने के लिए इस के लिए वस्तु के दायरे में होना चाहिए!


1
आप अनाम आंतरिक वर्ग के भीतर एक गैर-अंतिम चर का उपयोग नहीं कर सकते। यदि iCurrentSelectionइस अनाम वर्ग के भीतर चर घोषित किया जाता है तो यह ठीक काम करेगा। आप इसे -1 में इनिशियलाइज़ कर सकते हैं, ताकि पहली कॉल पर कोड निष्पादित हो जाए।
डेहविद

2
@dahvyd सही था यदि आप इसका उपयोग करते हैं तो इंट को अंतिम होना चाहिए। किसी भी मामले में यह वास्तव में अच्छी तरह से काम करता है। यदि स्थिति 0 का चयन नहीं किया गया था और यदि इसे फिर से सक्षम किया गया तो मैं एक EditText फ़ील्ड को अक्षम कर रहा था। इसके लिए धन्यवाद।
दिनांक ३

8

अपना स्पिनर नाम ढूंढें और आईडी ढूंढें फिर इस विधि को लागू करें।

spinnername.setOnItemSelectedListener(new OnItemSelectedListener() {

    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
        // your code here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        // your code here
    }
});

8

इससे कोई फर्क नहीं पड़ता कि आप OnItemSelectedListener को onCreate या onStart में सेट करेंगे - इसे अभी भी गतिविधि निर्माण या प्रारंभ (क्रमशः) के दौरान कहा जाएगा।
तो हम इसे onCreate में सेट कर सकते हैं (और onStart में नहीं!)।
पहले प्रारंभिककरण का पता लगाने के लिए एक ध्वज जोड़ें:

private Spinner mSpinner;
private boolean mSpinnerInitialized;

फिर onCreate (या onCreateView) में बस:

mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                if (!mSpinnerInitialized) {
                    mSpinnerInitialized = true;
                    return;
                }

                // do stuff
            }

            public void onNothingSelected(AdapterView<?> adapterView) {
                return;
            }
        });

1
इस ध्वज का उपयोग करने के लिए धन्यवाद।
जवां आर।

7

स्पिनर-विजेट के लिए डॉक्स कहते हैं

एक स्पिनर आइटम क्लिक आयोजनों का समर्थन नहीं करता है।

आपको setOnItemSelectedListenerअपनी समस्या को संभालने के लिए उपयोग करना चाहिए ।


6
spinner1.setOnItemSelectedListener(
    new AdapterView.OnItemSelectedListener() {
        //add some code here
    }
);

1
यह कॉलबैक के मुद्दे को संबोधित नहीं करता है जब स्पिनर को पहली बार शुरू किया जाता है (इस प्रकार एक प्रतिक्रिया को भड़काने के लिए जो वास्तव में चयनित होने वाले आइटम के साथ कुछ नहीं करना है)।
येवगेनी सिम्किन

4

स्पिनर के वर्तमान चयन के लिए एक वैश्विक चर लें:

int currentItem = 0;

spinner_counter = (Spinner)findViewById(R.id.spinner_counter);
String[] value={"20","40","60","80","100","All"};
aa=new ArrayAdapter<String>(this,R.layout.spinner_item_profile,value);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_counter.setAdapter(aa);

spinner_counter.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if(currentItem == position){
                return; //do nothing
            }
            else
            {
                 TextView spinner_item_text = (TextView) view;
                 //write your code here
            }
            currentItem = position;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

//R.layout.spinner_item_profile
<?xml version="1.0" encoding="utf-8"?>

<TextView  android:id="@+id/spinner_item_text"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" 
android:layout_height="wrap_content"
android:background="@drawable/border_close_profile"
android:gravity="start"  
android:textColor="@color/black"         
android:paddingLeft="5dip"
android:paddingStart="5dip"
android:paddingTop="12dip"
android:paddingBottom="12dip"
/>

//drawable/border_close_profile
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
   <shape android:shape="rectangle">
    <solid android:color="#e2e3d7" />
   </shape>
 </item>
<item android:left="1dp"
android:right="1dp"
android:top="1dp"
android:bottom="1dp">
<shape android:shape="rectangle">
    <solid android:color="@color/white_text" />
</shape>
</item>
</layer-list>

4

यदि आप एक सच्चे onChangedListener () चाहते हैं। शुरुआती मूल्य को हैंडलर में स्टोर करें और देखें कि क्या यह बदल गया है। यह सरल है और इसके लिए वैश्विक वैरिएबल की आवश्यकता नहीं है। काम करता है अगर आपके पास पृष्ठ पर एक से अधिक स्पिनर हैं।

String initialValue = // get from Database or your object
mySpinner.setOnItemSelectedListener(new SpinnerSelectedListener(initialValue));

...

protected class SpinnerSelectedListener implements AdapterView.OnItemSelectedListener {

        private SpinnerSelectedListener() {
            super();
        }

        public SpinnerSelectedListener(String initialValue) {
            this();
            this.initialValue = initialValue;
        }

        private String initialValue;

        // getter and setter removed.  

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            final String newValue = (String) spinHeight.getItemAtPosition(position);
            if (newValue.equals(initialValue) == false) {
               // Add your code here.  The spinner has changed value. 

               // Maybe useful.   
               // initialValue = newValue;
            }

        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
               // Maybe useful.   
               // initialValue = null; 
        }
    }

ऑब्जेक्ट्स आपके मित्र हैं, उनका उपयोग करें।


3
spinner.setOnItemSelectedListener(
            new AdapterView.OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> arg0, View arg1,
                        int arg2, long arg3) {

                    // TODO Auto-generated method stub
                }

                @Override
                public void onNothingSelected(AdapterView<?> arg0) {
                    // TODO Auto-generated method stub

                }
                //add some code here
            }
        );

1

यह स्पिनर को खोजने और खोज निकालेगा और यह काम करेगा

    Spinner schemeStatusSpinner;

  schemeStatusSpinner = (Spinner) dialog.findViewById(R.id.spinner);

schemeStatusSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
            // your code here
            if(schemeStatusSpinner.getSelectedItemId()==4){
                reasonll.setVisibility(View.VISIBLE);
            }
            else {
                reasonll.setVisibility(View.GONE);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parentView) {
            // your code here
        }

    });

1

सबसे अच्छा तरीका है जो मुझे लगता है कि एक flagitemselected = 0;में होगा onCreate()। और आइटम चयनित घटना वृद्धि पर है कि झंडा यानी flagitemselected++; और फिर जाँच करें

if(flagitemselected!=1)
{
// do your work here
}

इससे मुझे अनुमान लगाने में मदद मिलेगी।


0

एक चाल मैंने पाया कि आपके सेटऑन इटसेलेक्टेड लिस्ट्रेन को ऑनक्राउट के बजाय ऑनविन्डफोकसचेंज में डाला गया है। मैंने इसे इस तरह से करने के लिए कोई बुरा दुष्प्रभाव नहीं पाया है, फिर भी। मूल रूप से, खिड़की तैयार होने के बाद श्रोताओं को सेट करें। मुझे यकीन नहीं है कि कितनी बार onWindowFocusChanged चलता है, लेकिन यह आसान है कि आप अपने आप को लॉक वैरिएबल बना सकें, यदि आप इसे बहुत बार चला रहे हैं।

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


0

डिफ़ॉल्ट रूप से, आपको स्पिनर सरणी का पहला आइटम मिलेगा

value = spinner.getSelectedItem().toString();

जब भी आपने स्पिनर में मूल्य का चयन किया यह आपको चयनित मूल्य देगा

यदि आप चयनित आइटम की स्थिति चाहते हैं, तो इसे इस तरह से करें

pos = spinner.getSelectedItemPosition();

उपरोक्त दो उत्तर श्रोता को लागू किए बिना हैं

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