CursorTreeAdapter更新Cursor后分组折叠/分组Cursor不刷新问题
核心问题说明
调用notifyDataSetChanged()不会刷新Adapter绑定的底层Cursor,所以分组数据不会更新;调用requery()刷新Cursor后,ExpandableListView会默认重置所有分组的展开状态,所以会出现自动折叠的情况。
具体实现方案
- 刷新数据前,先记录所有处于展开状态的分组的唯一标识(这里用分组查询的
FIN_ID,和你的分组聚合逻辑对应,不会因为数据更新发生变化) - 手动重新查询分组Cursor,调用
setGroupCursor()替换Adapter的旧Cursor,该方法会自动触发分组视图重绘、子项Cursor重新查询 - 遍历更新后的所有分组,将之前记录的已展开分组重新设置为展开状态
修改后的Handler代码
public android.os.Handler mRefreshHandler = new Handler() { @Override public void handleMessage(android.os.Message msg) { new SummaryTask().execute(); // 保存已展开分组的FIN_ID HashSet<String> expandedFinIds = new HashSet<>(); int oldGroupCount = mShipKitExpandableListAdapter.getGroupCount(); for (int i = 0; i < oldGroupCount; i++) { if (mShipKitExpandableListView.isGroupExpanded(i)) { Cursor groupCursor = (Cursor) mShipKitExpandableListAdapter.getGroup(i); String finId = groupCursor.getString(groupCursor.getColumnIndex( DbSchemaKitting.KitSchema.TABLE_NAME + "dot" + DbSchemaKitting.KitSchema.COLUMN_FIN_ID )); expandedFinIds.add(finId); } } // 替换为新查询的分组Cursor Cursor newGroupCursor = DbSingleton.getInstance().getDatabase().rawQuery(getGroupQuery(), null); mShipKitExpandableListAdapter.setGroupCursor(newGroupCursor); // 恢复展开状态 int newGroupCount = mShipKitExpandableListAdapter.getGroupCount(); for (int i = 0; i < newGroupCount; i++) { Cursor groupCursor = (Cursor) mShipKitExpandableListAdapter.getGroup(i); String finId = groupCursor.getString(groupCursor.getColumnIndex( DbSchemaKitting.KitSchema.TABLE_NAME + "dot" + DbSchemaKitting.KitSchema.COLUMN_FIN_ID )); if (expandedFinIds.contains(finId)) { mShipKitExpandableListView.expandGroup(i); } } } };
注意事项
- 不要使用已废弃的
requery()方法,手动重新查询替换Cursor的兼容性和稳定性更好 - 不要用分组位置作为展开状态的标识,新增/删除分组可能导致位置错位,用业务唯一ID(如这里的FIN_ID)匹配更可靠
- 若有新增的分组,默认会保持折叠状态,符合常规交互逻辑,如有需求可单独处理新增分组的展开逻辑
内容的提问来源于stack exchange,提问作者moonlightcheese
相关产品推荐
相关产品推荐

