我正在扩展一个ExpandableListView来创建我自己的listview,并且适配器回调是通过以下方式实现的:
@Override
public int getGroupCount() {
return m_FilteredSites.getSize();
}
@Override
public Object getGroup(int i) {
return m_FilteredSites.get(i);
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
SiteEntity site = (SiteEntity) getGroup(groupPosition);
//more code ....
}
问题是在调用getGroupCount和getGroupView之间,m_FilteredSites集合可以更改(由于我的情况下使用了过滤器)。 有没有办法强制同步或任何其他方法,以保持呼叫之间的数据一致?
答案 0 :(得分:1)
您不应更改之外的内部数据。相反,您可以构建新的适配器,然后使用该方法更改它,一切都会没问题。setAdapter()
此视频适用于ListView
,但也适用于ExpandableListView
:Google I/O 2010 - The world of ListView。如果你有时间,我认为值得一看。
对不起,我不记得我从哪里学到了。我刚刚重新观看了上面的视频,却找不到那一刻。我认为当列表中项目的数据发生变化而不是列表本身时,会使用notifyDataSetChanged()
。现在,如果我没记错,你应该这样做:
public class SampleAdapter extends BaseExpandableListAdapter {
private List<List<String>> mData;
public void updateData(List<List<String>> data) {
mData = data;
notifyDataSetChanged();
}
}
我的意思是您不应更改mData
的项目(例如add()
,remove()
...)。最好建立新的列表并将其分配给mData
,就像上面的代码一样。
如果您有content provider,则可以使用CursorTreeAdapter
,它会自动为您管理数据集。我强烈建议使用内容提供商。
答案 1 :(得分:1)
问题现已解决。 问题是我在工作线程而不是UI线程上更改了m_FilteredSites集合。 Filter类有2个回调: 1. performFiltering - 在工作线程上执行。 2. publishResults - 在UI线程上执行。
最初我正在计算过滤器,但也在performFiltering方法上修改m_FilteredSites。 修复方法是将更改m_FilteredSites集合的实际代码移动到publishResults方法。
答案 2 :(得分:0)
您可以同步自己的代码,而不是同时访问它,例如:
ExpandableListView elv;
synchronized(elv) {
// Do whatever with elv that requires exclusive thread access
}