我很久以前就注意到了这个问题,但直到现在我才能准备好演示,并清楚地再现它。问题是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();
}
}
知道为什么会发生这种情况,并且在大多数情况下是因为更新listview适配器(或者可能是某些视图更新)?如果我删除行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。
我想要的是找到一种最有效的方法来使视图和操作栏无效而不会破坏它。
答案 0 :(得分:0)
我不明白为什么你在doInBackground中这样做了:
的Thread.sleep(randomSleep);
但是,在“LoadingTask”类中,注释“doInBackground”中的行将解决问题。
请参阅:
@Override
protected Void doInBackground(Void... params)
{
// int randomSleep = (int) (Math.random() * 1000);
// try
// {
// Thread.sleep(randomSleep);
// } catch (InterruptedException e)
// {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
return null;
}