android onitemselected参数,Android spinner onItemSelected called multiple tim

可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):

问题:

I have a layout with three spinners. They differ in the option presented in the drop-down.

In my onCreateView I have a method to setup the spinners. Inside that method I have something like this:

mySpinner = (Spinner) view.findViewById(R.id.my_spinner);

ArrayAdapter mySpinner =

new ArrayAdapter(getActivity(), R.layout.background,

new ArrayList(Arrays.asList(getResources().getStringArray(R.array.spinner_one_data))));

mySpinner.setDropDownViewResource(R.layout.spinner_text);

mySpinner.setAdapter(mySpinner);

mySpinner.setOnItemSelectedListener(this);

As I said, my other two spinners are almost the same but with different options.

I know that onItemSelected is called once for every spinner in a "first setup" so I have a flag to prevent this problem. With this flag solution, my spinners are working as expected.

The problem is when I select in each spinner an option and then rotate the screen. Now, onItemSelected is called 6 times instead the 3 times that I was expecting (I've set a flag to manage this situation of the 3 times calling).

Why Is it happening and hoe should I handle this?

回答1:

In general, I've found that there are many different events that can trigger the onItemSelected method, and it is difficult to keep track of all of them. Instead, I found it simpler to use an OnTouchListener to only respond to user-initiated changes.

Create your listener for the spinner:

public class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener {

boolean userSelect = false;

@Override

public boolean onTouch(View v, MotionEvent event) {

userSelect = true;

return false;

}

@Override

public void onItemSelected(AdapterView> parent, View view, int pos, long id) {

if (userSelect) {

// Your selection handling code here

userSelect = false;

}

}

}

Add the listener to the spinner as both an OnItemSelectedListener and an OnTouchListener:

SpinnerInteractionListener listener = new SpinnerInteractionListener();

mSpinnerView.setOnTouchListener(listener);

mSpinnerView.setOnItemSelectedListener(listener);

回答2:

I've found a solution that is working for me.

I have the 3 spinners so onItemSelected is called 3 times at the initial spinner setup. To avoid onItemSelected from firing a method in the initial setup I've created a counter so onItemSelected only fires the method accordingly the counter value.

I've realized that in my situation, if a rotated the screen, onItemSelected is fired again the 3 times, plus a time for each spinner that is not in the position 0.

An example:

I have the 3 spinners and the user changes 2 of them to one of the available option other then position 0 so he ends up with a situation like this:

First spinner - > Item 2 selected

Second spinner -> Item 0 selected (no changes)

Third spinner -> Item 1 selected

Now, wen I rotate the screen, onItemSelected will be fired 3 times for the initial spinner setup plus 2 times for the spinners that aren't at position 0.

@Override

public void onSaveInstanceState(Bundle outState) {

int changedSpinners = 0;

if (spinner1.getSelectedItemPosition() != 0) {

changedSpinners += 1;

}

if (spinner2.getSelectedItemPosition() != 0) {

changedSpinners += 1;

}

if (spinner3.getSelectedItemPosition() != 0) {

changedSpinners += 1;

}

outState.putInt("changedSpinners", changedSpinners);

}

I've saved the state in onSaveInstanceState and then, in onCreateView I checked if savedInstanceState != null and if so, extracted changedSpinners from the bundle and updated my counter to act accordingly.

回答3:

To expand on Andres Q.'s answer... If you are using Java 8 you can do this with fewer lines of code by making use of lambda expressions. This method also forgoes the need to create a separate class in order to implement onTouchListener

Boolean spinnerTouched; //declare this as an instance or class variable

spinnerTouched = false;

yourSpinner.setOnTouchListener((v,me) -> {spinnerTouched = true; v.performClick(); return false;});

yourSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

@Override

public void onItemSelected(AdapterView> parent, View view, int position, long id) {

if(spinnerTouched){

//do your stuff here

}

}

@Override

public void onNothingSelected(AdapterView> parent) {

//nothing selected

}

});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值