簡體   English   中英

Android Spinner:獲取選中的項目改變事件

[英]Android Spinner: Get the selected item change event

當所選項目更改時,如何為 Spinner 設置事件偵聽器?

基本上我想做的是類似於這樣的事情:

spinner1.onSelectionChange = handleSelectionChange;

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

之前的一些答案是不正確的。 它們適用於其他小部件和視圖,但Spinner 小部件的文檔明確指出:

微調器不支持項目點擊事件。 調用此方法將引發異常。

最好使用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()方法調用中。

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

注意:記住一件事。

Spinner OnItemSelectedListener事件將執行兩次:

  1. 微調器初始化
  2. 用戶手動選擇

嘗試通過使用標志變量來區分這兩者。

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

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應該在對象范圍內才能工作!

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

找到您的微調器名稱並找到 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
    }
});

Spinner-widget 的文檔說

微調器不支持項目點擊事件。

您應該使用setOnItemSelectedListener來處理您的問題。

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

對於 kotlin,您可以使用:

spinner.onItemSelectedListener =  object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        
    }

    override fun onNothingSelected(p0: AdapterView<*>?) {
        
    }
}

注意:對於onItemSelected方法的參數,我使用自定義變量名稱

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

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>

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

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

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

默認情況下,您將通過

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

每當您在微調器中選擇值時,這都會為您提供所選值

如果你想要所選項目的位置,那么就這樣做

pos = spinner.getSelectedItemPosition();

以上兩個答案是針對沒有應用監聽器的

這將工作初始化微調器和 findviewbyid 並使用它它會工作

    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
        }

    });

我認為最好的方法是讓flagitemselected = 0; onCreate() 並且在 item selected 事件上增加那個標志,即flagitemselected++ 然后檢查

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

這將有助於我猜。

我發現的一個技巧是將您的 setOnItemSelectedListeners 放在 onWindowFocusChanged 而不是 onCreate。 我還沒有發現這樣做有任何不好的副作用。 基本上,在繪制窗口后設置偵聽器。 我不確定 onWindowFocusChanged 運行的頻率,但是如果您發現它運行得太頻繁,可以很容易地為自己創建一個鎖定變量。

我認為 Android 可能正在使用基於消息的處理系統,如果您將其全部放在 onCreate 中,您可能會遇到在繪制后填充微調器的情況。 因此,您的偵聽器將在您設置項目位置后觸發。 當然,這是一個有根據的猜測,但請隨時糾正我。

我知道這早就解決了,但我的字符串數組頂部有一個“請選擇”字符串。 然后當你寫監聽器時

yourspinner.onItemSelectedListener = object : OnItemSelectedListener {
            override fun onItemSelected(adapterView: AdapterView<*>?, view: View, i: Int, l: Long) {
                yourvalue = yourspinner.getSelectedItem().toString()

                when(yourvalue){
                    "Please Select" -> // DO nothing
                    else -> // Do something
                }
            }

            override fun onNothingSelected(adapterView: AdapterView<*>?) {
                return
            }
        }

您當然可以擴展 when 語句以具有不同的響應或操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM