Spin ner:通过点击监听器以编程方式选择项目

问题描述 投票:0回答:1

假设我有一个带有以下项目的微调器:“ A”,“ B”,“ C”。如果用户尚未选择任何内容,则微调器将显示“未知”。

STEP ONE,用户过去可能已经选择了一个项目。因此,我在视图模型中加载数据,然后hasSelectedSomething在视图模型中观察到LiveData(对BE的异步调用,它将更新LiveData):

viewModel.itemLiveData.observe(
        viewLifecycleOwner,
        Observer { item ->
            hasSelectedSomething = (item != "unknown")
        }
)

STEP TWO现在,我设置了微调器。如果用户尚未选择任何选项,我希望在“未知”项目中选择微调框,否则,我希望在用户之前选择的任何位置选择它。

if(!hasSelectedSomething) {
    spinner.setSelection(itemAdapter.getPosition("unknown"))
} else {
    spinner.setSelection(itemAdapter.getPosition(viewModel.getItemString()))
}

第三步我实现了spinner.onItemSelectedListener

spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(parent: AdapterView<*>?, view: View?, pos: Int, id: Long) {
            val selectedItem = spinner.getItemAtPosition(pos) as String

            viewModel.updateItemWithSelection(selectedItem)
        }

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

我的问题LiveData的默认值为“ unknown”,这意味着微调器应从“ unknown”开始。然后,假设用户过去选择了“ B”,因此我以编程方式将微调器设置为“ B”。问题是.setSelection触发onItemSelected,将pos设置为任意选择,此时pos对应于“未知”。因此,发生的情况是LiveData从“未知”(默认值)变为“ B”(从调用到BE的结果)到“未知”(onItemSelected选择了“未知”,因此它将该值传递给视图模型)。

我该如何解决这个问题?如何正确设置微调器,使其处理默认值,用户选择和以前的选择?

android kotlin spinner
1个回答
0
投票

通常,如果onItemSelected的回调中包含逻辑,并且需要以编程方式设置项目,则通常的做法是:

(伪代码)

yourCallback = object: AdapterView.OnItemSelectedListener {
  ...
}

spinner.setOnItemSelected(null)
spinner.setValue(...)
spinner.setOnItemSelected(yourCallback)

因此,在强制微调器设置值之前,请始终删除回调。

“未知”应该是您的选择中的一项。 Spinner(afaicr)不支持“ null”(自2016年以来,我不得不最后一次使用它,它可能已更改),但ViewModel会吐一个值。

最后,不要在用户界面(if(!hasSelectedSomething) {)中仅使viewModel吐出一个值(未知有效值),而让微调器简单地设置其值。 (记住要删除回调,设置值,再次设置回调以防止再次调用)。

您有一个ViewModel是有原因的,让UI通过观察微调器的值来简单地对状态变化做出反应。

© www.soinside.com 2019 - 2024. All rights reserved.