如何在通过代码设置选定项时禁用onItemSelectedListener被调用

39

想知道如何解决以下问题:根据两个Spinner所选项来计算结果。为了处理UI,即用户在一个Spinner中选择一个新项,我在活动的onCreate()方法中使用setOnItemSelectedListener安装了一个监听器。

现在:这当然可以正常工作。监听器的工作是触发对结果的新计算。

问题在于:由于我拦截了onPause()onResume()以保存/恢复上一次的状态,我编写了一个方法来编程方式地设置这两个Spinner的选定项,就像这里一样:

startSpinner.setSelection(pStart);
destSpinner.setSelection(pDest);

这两个调用也会调用监听器!我的结果计算方法以及通知新结果集的方法在此处被调用了两次!

这种情况下,一个愚蠢的直接方式是使用布尔变量禁用监听器内部执行的任何操作,在设置所选项目之前设置它,并在之后重新设置。 好吧。但有更好的方法吗?

我不希望代码行动调用监听器,只希望用户行动调用它们! :-(

你怎么做到的? 谢谢!


你可以使用 setSelection(pStart, false) 来设置 animate 参数。但这并不总是有效。 - sunlover3
13个回答

1
在我的情况下,由于我在程序中触发了旋转器,所以我只需要在spinner.performClick()之后添加spinnerSelected标志,如下所示。
private var spinnerSelected = false

someView.setOnClickListener {
    spinner.performClick()
    spinnerSelected = true
}

spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onNothingSelected(parent: AdapterView<*>?) {
        // do nothing
    }

    override fun onItemSelected(
        parent: AdapterView<*>?,
        view: View?,
        position: Int,
        id: Long
    ) {
        if (spinnerSelected) {
            //... do something

            spinnerSelected = false
        }
      }
    }

0
    This following method will help you to stop invoking automatically the selection listener


    yourspinnerobj.post(new Runnable() {
                @Override
                public void run() {
                    yourspinnerobj.setOnItemSelectedListener(yourspinnerlistener);
                }
            });

0
这是我的答案:spinner.setClickable(false); 告诉 spinner 在执行 setSelection 函数之前,这不是一个可点击的事件,然后使用 spinner.setClickable(true); 在执行 setSelection 函数后恢复它。另一方面,它还可以防止用户在执行 setSelection 函数期间点击 spinner,尽管这种情况的机会太小,但应该在代码中处理。
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id){
    if(!selectFridaSpinner.isClickable())return;
}

spinner.setClickable(false);
spinner.setSelection(2);
spinner.setClickable(true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接