我有一个微调器,用于过滤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也不会立即被调用。如果是这种情况,如何让消息队列(looper?)立即处理所有待处理事件?
我可能忽略了更优雅的解决方案吗?
答案 0 :(得分:2)
我认为它可能与UI线程的消息队列没有立即执行有关,因为这个onItemSelected也不会立即被调用。
正确,或多或少。当这一切都由队列和主应用程序线程处理时,您对setSelection()
的调用将触发onItemSelected()
。
如果是这种情况,如何让消息队列(looper?)立即处理所有待处理事件?
你没有。
我可能忽略了更优雅的解决方案吗?
您应该能够将listView.setItemChecked(adapter.getPosition(item), true);
包裹在Runnable
中,并通过调用post()
(可在任何View
上提供)将其添加到队列中。这应该导致上述代码在onItemSelected()
处理完毕后运行。