1

我正在扩展 ExpandableListView 以创建自己的列表视图,并且适配器回调以下列方式实现:

@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 集合可能会发生变化(由于在我的情况下使用了过滤器)。有没有办法强制同步或任何其他方法来保持调用之间的数据一致?

4

3 回答 3

1

您不应该更改setAdapter(). 相反,您可以构建新的适配器,然后使用该方法对其进行更改,一切都会好起来的。

该视频适用于ListView,但也适用于ExpandableListViewGoogle I/O 2010 - 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上面的代码。

如果您有内容提供商,您可以使用CursorTreeAdapter它,它会自动为您管理数据集。我强烈建议使用内容提供商。

于 2013-02-28T09:11:56.127 回答
1

现在问题已解决。问题是我在工作线程而不是 UI 线程上更改 m_FilteredSites 集合。Filter 类有 2 个回调: 1. performFiltering - 在工作线程上执行。2. publishResults - 在 UI 线程上执行。

最初我在计算过滤器,但也在 performFiltering 方法上修改 m_FilteredSites。解决方法是将更改 m_FilteredSites 集合的实际代码移动到 publishResults 方法。

于 2013-04-24T08:38:54.517 回答
0

您可以同步自己的代码以顺序访问它而不是同时访问它,例如:

ExpandableListView elv;

synchronized(elv) {
    // Do whatever with elv that requires exclusive thread access
}
于 2013-02-28T09:06:43.887 回答