【问题标题】:ExpandableListView callbacks not synchronizedExpandableListView 回调不同步
【发布时间】:2013-02-28 09:03:54
【问题描述】:

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

【问题讨论】:

    标签: android listview synchronization expandablelistview expandablelistadapter


    【解决方案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,它会自动为您管理数据集。我强烈推荐使用内容提供商。

    【讨论】:

    • 你的回答听起来很有道理。然而,适配器中的 notifyDataSetChanged 方法不是证明可以在不重新创建适配器的情况下更改其内部数据吗?
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      ExpandableListView elv;
      
      synchronized(elv) {
          // Do whatever with elv that requires exclusive thread access
      }
      

      【讨论】:

      • 我看不出同步我的代码会有什么帮助。我不控制流程 - 这些是系统回调。例如,系统将 1. 调用 getGroupCount 并获取数字 3(同步块结束)。 2.现在我更改另一个同步块中的数据,项目数变为0。 3.现在系统调用数字2的getGroupView,因为它仍然认为项目数是3。繁荣。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多