Spinner(3): OnItemSelectedListener 觸發時機

來源:互聯網
上載者:User

部落格 Spinner(1): 由SDK引發的問題、Spinner(2): 動態添加資源 簡單介紹了spinner,但是 Spinner 還有陷阱,所以使用時應該注意。

本篇部落格繼續探討Spinner及其注意事項,歡迎拍磚。

為 Spinner 設定 OnItemSelectedListener、OnTouchListener、OnFocusChangeListener 事件,看看在什麼情況下觸發這些事件。

看代碼,如下:

package mark.zhang;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Spinner;public class SpinnerTestActivity extends Activity {private static final String[] strArrays = {"w" , "x", "y", "z"};private Spinner mSpinner;private ArrayAdapter<String> adapter;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mSpinner = (Spinner) findViewById(R.id.mySpinner);adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, strArrays);// 自訂spinner下拉樣式adapter.setDropDownViewResource(R.layout.myspinner_dropdown);mSpinner.setAdapter(adapter);// 設定選擇條目事件mSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {Log.d("mark", "onItemSelected() is invoked!");arg0.setVisibility(View.VISIBLE);}@Overridepublic void onNothingSelected(AdapterView<?> arg0) {}});// 設定觸摸事件監聽mSpinner.setOnTouchListener(new Spinner.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {Log.d("mark", "onTouch() is invoked!");v.setVisibility(View.INVISIBLE);return false;}});// 設定焦點變化事件監聽mSpinner.setOnFocusChangeListener(new Spinner.OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {Log.d("mark", " onFocusChange() is invoked!");}});}}

代碼中,建立 ArrayAdapter 對象的同時,為 spinner 添加備選項目:

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, strArrays);

直接運行該 Android project,看看效果:

D/mark    ( 1799): onItemSelected() is invoked!

注意:此時spinner中有預設顯示值。

可以看出,OnItemSelectedListener 監聽事件 onItemSelected 被調用。這就很讓人奇怪,根本沒有點擊 Spinner,為何會觸發該事件呢???

如果您好奇的話,跟我一起測試吧!

這樣來建立ArrayAdapter對象:

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);

運行,沒有任何資訊出現。說明此時沒有觸發上述的任何監聽器設定的監聽器。

注意:此時 spinner 中沒有任何預設顯示值。

再做一個測試,修改代碼如下:

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);for(int i = 0; i<5; i++) {adapter.add("mark" + i);}

運行:

D/mark    ( 5890): onItemSelected() is invoked!

呵呵,OnItemSelectedListener 監聽事件 onItemSelected 被調用。

當我們點擊 Spinner 的下拉式清單時,一定會觸發 OnTouchListener的onTouch 事件。但是不一定會觸發 OnItemSelectedListener的onItemSelected 事件。


如果,當前 Spinner 的預設顯示是 mark0,那麼再次點擊 mark0 的話,列印結果:

D/mark    ( 5890): onTouch() is invoked!D/mark    ( 5890): onTouch() is invoked!

可以看出,OnItemSelectedListener 的 onItemSelected 事件沒有被觸發,但是 OnTouchListener的onTouch 事件被觸發兩次。

如果,你點擊選項列表的其它值如 mark1,列印結果:

D/mark    ( 5890): onTouch() is invoked!D/mark    ( 5890): onTouch() is invoked!D/mark    ( 5890): onItemSelected() is invoked!

呵呵,很戲劇化!

最後一個問題,何時觸發 OnFocusChangeListener 事件,很簡單,運行 App 之後,隨便改變當前焦點,就會觸發該事件。

知道這樣的結果之後,很無語!但是知道總比不知道好,至少您可以採取一點措施來避免一些不必要的麻煩。

比如,每次都想擷取 spinner 的值,就可以為其綁定 onTouch 事件(因為該事件每次點擊都會被觸發),但是注意,點擊 spinner 一次,會觸發該事件很多次(touch 包括很多動作如 down、up、move),那麽我們就在 event 事件的 down 事件裡面寫我們的代碼。即按下有效,up、move 等無效即可。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.