2009-08-26 85 views
304

如何在選定項目更改時爲微調器設置事件偵聽器?Android微調:獲取所選項目更改事件

基本上什麼,我試圖做的是類似於此:

spinner1.onSelectionChange = handleSelectionChange; 

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

我已經試過這些問題的答案,但沒有人是有益的。一旦微調組件不支持項目點擊事件。 [微調文檔](http://developer.android.com/reference/android/widget/Spinner.h) – 2012-06-20 19:32:13

回答

657

一些以前的答案是不正確的。他們對其他部件和意見的工作,但對於Spinner widget文件明確規定:

噴絲不支持項目點擊 事件。調用此方法會引發 例外。

更好地利用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()方法調用中。

+33

這個問題在於,在構建視圖時,也會調用onItemSelected方法。所以寫在那裏的代碼也會在啓動時執行。只有當用戶調用了真實的項目選擇時,纔有執行包含代碼的方法嗎? – Kennethvr 2010-12-28 11:53:16

+32

實際上,可以通過將setOnItemSelectedListener置於OnStart方法而不是onCreate方法來解決該問題。愚蠢的我... – Kennethvr 2010-12-28 12:05:13

+11

我已經把監聽器放在onStart方法中,但是在用戶看到任何東西之前調用它,就像onCreate一樣,所以在我的情況下,一個「繼續」按鈕意味着不可見直到用戶選擇某件東西,該按鈕在初始顯示時變爲可見。你是說你的經歷不同嗎?如果是這樣,那麼我在缺少onStart方法時做了什麼不同? – 2011-02-28 18:47:51

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

這並不解決這個回調的問題,當旋轉器剛啓動時(因此挑起響應被稱爲這與實際選擇的項目無關)。 – 2011-02-28 18:45:31

5

的微調,插件的文件說:「一個微調不支持產品Click事件。」 你應該使用「setOnItemSelectedListener」來處理你的問題

0

Stefan Klumpp的輝煌以上也幫了我很多。謝謝。 我是新手,其中的「@Override」引起了一個關於「必須重寫相同名稱的超類方法」的錯誤。 Eclipse建議我應該刪除Overrides。當我這樣做,它的工作。請不要問我如何或爲什麼。

+2

您的Eclipse環境可能設置爲Java 1.6。 Android僅與Java 1.5兼容,其中'@ Override'註釋不允許用於接口方法。 – 2009-12-31 16:01:34

41
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

    我也被叫過兩次!我無法弄清楚你是如何區分這兩者的? – MAC 2010-06-26 00:09:46

    +11

    只需設置一個像布爾值一樣的全局布爾值initialDisplay = true;然後在onSelect中查看它是否爲真,如果是,則不要在select上做任何其他操作,但將標誌設置爲false,以便下一次調用該標誌(當用戶實際選擇時)。 – 2011-02-28 19:41:42

    +0

    有關執行OnclickListener的最佳解釋。 – 2011-08-22 10:37:34

    8

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

    可以避開OnItemSelectedListener()被調用了簡單的檢查:存儲當前選擇指數整型變量,而做任何事情之前,onItemSelected(..)內進行檢查。

    E.g:

    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應該是在對象範圍內這個工作!

    +0

    您不能在匿名內部類中使用非最終變量。如果在這個匿名類中聲明'iCurrentSelection'變量,它將會正常工作。您可以將其初始化爲-1,以便在第一次調用時執行代碼。 – dahvyd 2012-05-19 06:44:43

    +0

    @dahvyd是正確的,如果你使用這個int必須是final的。無論如何它運作得非常好。如果位置0沒有被選中,並且它改變了,重新啓用它,我禁用了EditText字段。謝謝你。 – natur3 2015-01-07 18:07:50

    +0

    現在,這是一個問題的解決方案! – goonerDroid 2016-11-18 05:35:20

    0

    我認爲最好的方法是有flagitemselected = 0;在創造。並在項目上選擇事件增量該標誌即flagitemlected ++;然後檢查是否(flagitemselected!= 1){//在這裏做你的工作。這}將幫助我猜

    -1

    一招我發現這是把你的setOnItemSelectedListeners在onWindowFocusChanged代替的onCreate。我還沒有發現這樣做的不良副作用。基本上,窗口繪製後設置聽衆。我不確定onWindowFocusChanged的運行頻率,但如果您發現它運行得太頻繁,則很容易創建一個鎖定變量。

    我認爲Android可能會使用基於消息的處理系統,如果你把它全部的onCreate,你可能會碰到那裏得到延伸後的微調被填充的情況。所以,當你設置物品位置後,你的聽衆會開火。當然,這是一個有教養的猜測,但請隨時糾正我。

    4

    找到你的微調名字,找到然後ID實現此方法。

    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 
        } 
    }); 
    
    15

    您可以在您的活動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(""); 
    } 
    
    1
    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 
          } 
         ); 
    
    3

    採取一個全局變量微調的當前選擇:

    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> 
    
    +0

    這個工作對我來說..真棒之一 – 2016-10-05 06:00:32

    2

    在OnCreate或onStart中設置OnItemSelectedListener無關緊要 - 它將在創建Activity或啓動(分別)期間繼續調用。
    因此,我們可以將其設置成的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

    謝謝你使用這個標誌。 – 2017-06-28 17:08:38

    +1

    你救了我的一天,謝謝你。 – 2018-02-12 16:45:15

    2

    如果你想有一個真正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; 
         } 
        } 
    

    對象是你的朋友,使用它們。