0

我有一个微调器,可以过滤 OnItemSelected 中的适配器。像这样:

@Override
public void onItemSelected(AdapterView<?> av, View v, int position, long id) {
    switch (av.getId()) {
    case R.id.spfilteroptions:
        adapter.getFilter().refresh(); // <- what this post is about
        break;
    }
}

所以现在我想做:

spinner.setSelection(...)

然后作为我的下一条指令:

listView.setItemChecked(adapter.getPosition(item), true);

第二条指令依赖于已经完成过滤操作的 onItemSelected 回调,因为 getPosition 只有在应用过滤器后才返回正确的值(显然)

所以我认为这段代码不是最优的,因为

adapter.getFilter().refresh();

在后台完成并且 listView.setItemChecked(position, true) 在完成过滤之前当然会被调用。

所以我这样做:

adapter.ignoreFilteringRequests(true) // my own method in the adapter that results in ignoring filter() requests
spinner.setSelection(...) // now onItemSelected callback should not trigger filtering...
adapter.ignoreFilteringRequests(false)
// now I have this instead:
adapter.getFilter().filter(myContraint, new Filter.FilterListener(){ 
   @Override
    public void onFilterComplete(int count) {
        listView.setItemChecked(adapter.getPosition(item), true);
    }

})

我注意到在 spinner.setSelection(...) 之后并没有立即调用 onItemSelected,而是在一段时间后调用。这会导致 onItemSelected 回调中的 filter() 也被执行,而不管 adapter.ignoreFilteringRequests()(在 setSelection() 之后再次设置为 false)。是什么导致了这种情况,我该如何避免这种情况?我在想这可能与未立即执行的 UI 线程的消息队列有关,因此也不会立即调用 onItemSelected。如果是这种情况,我如何使消息队列(循环器?)在继续之前立即处理所有待处理的事件?

有没有更优雅的解决方案我可能忽略了?

4

1 回答 1

2

I was thinking it may have to do with the message queue of the UI thread not executing immediately and because of this onItemSelected is not called immediately either.

Correct, more or less. Your call to setSelection() will trigger onItemSelected(), when this is all handled by the queue and main application thread.

If that is the case, how do I cause the message queue (looper?) to process all pending events immediately before moving on?

You don't.

Is there any more elegant solution to this I may have overlooked?

You should be able to wrap listView.setItemChecked(adapter.getPosition(item), true); in a Runnable and add it to the queue via a call to post() (available on any View). That should cause the aforementioned code to be run after onItemSelected() has processed.

于 2013-06-11T23:24:33.777 回答