我很久以前就注意到了这个问题,但直到现在我才能够准备清楚地重现它的演示。问题出现在 2.1 模拟器和我的 ICS 4.0.3 设备上。
在应用程序中,我有 AsyncTask ,它可以通过调用 invalidateOptionsMenu 来调整操作栏不确定进度和重新初始化菜单的可见性。这应该隐藏刷新图标。在我修改 listView 数据模型并在适配器上调用 notifyDataSetChanged 之前,这一切正常。此类操作后,Actionbar 可能已损坏视图。
预期视图:
损坏的视图(最后一项永远消失或在某些情况下添加了空白):
导致代码在 onPostExecute
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
for (int i = 0; i < 10; i++)
{
adapter.items.add(i);
}
adapter.notifyDataSetChanged();
activity.stopLoading();
}
...
void stopLoading()
{
if (loaders.decrementAndGet() == 0)
{
setSupportProgressBarIndeterminateVisibility(false);
invalidateOptionsMenu();
}
}
知道为什么会发生这种情况,并且在大多数情况下是因为更新了列表视图适配器(或者可能是一些视图更新)?如果我删除行 adapter.notifyDataSetChanged(); 演示中不会破坏操作栏。但在实际应用中,它也可能由于其他原因而损坏(无法准确确定所有问题原因)
演示问题的项目:http: //goo.gl/ZbMTU
打开 ActionBarSherlock 问题:https ://github.com/JakeWharton/ActionBarSherlock/issues/887
UPD:继续挖掘这个问题。似乎不完全是 adapter.notifyDataSetChanged() 导致无效的外观,但是 AdapterView.AdapterDataSetObserver 的 requestLayout 调用正在侦听 ListView 中的数据集更改事件
解决方法存在,我可以在 handler.post 中调用 invalidateOptionsMenu 和 setSupportProgressBarIndeterminateVisibility。但它甚至强制使用 FragmentPagerAdapter 的自定义实现,它在延迟的 handler.post 中调用 fragment.setHasOptionsMenu
我想要的是找到最有效的方法来使视图和操作栏无效而不破坏它。