ExpandableListView回调未同步

时间:2013-02-28 09:03:54

标签: android listview synchronization expandablelistview expandablelistadapter

我正在扩展一个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集合可以更改(由于我的情况下使用了过滤器)。 有没有办法强制同步或任何其他方法,以保持呼叫之间的数据一致?

3 个答案:

答案 0 :(得分:1)

您不应更改setAdapter() 之外的内部数据。相反,您可以构建新的适配器,然后使用该方法更改它,一切都会没问题。

此视频适用于ListView,但也适用于ExpandableListViewGoogle 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
}