如何在适配器数据更改时更新可扩展列表视图

时间:2009-09-23 04:11:00

标签: java android

我有一个扩展ExpandableListActivity的活动。我使用SimpleCursorTreeAdapter来填充ExpandableListView。 我的布局包含列表视图和空视图。 在应用程序启动时,ExpandableListActivity会自动选择要显示的右视图。

我的步骤:

  1. 应用程序启动,没有数据。 (屏幕上的空视图)
  2. 将一些数据插入db。
  3. 调用adapter.notifyDataSetChanged();但空视图仍然在屏幕上,我的列表视图中没有任何项目。
  4. 然后我重启app:

    1. 列表视图出现。我展开所有组并滚动到底部。
    2. 我点击列表中的项目。出现新活动。
    3. 点击后退按钮。所有组都已折叠,我们位于屏幕顶部。滚动位置和扩展组不会被记住。
    4. 从db中删除所有数据并调用adapter.notifyDataSetChanged();
    5. 子视图已消失,但顶级组仍然可见。
    6. 问题:

      1. 如何用列表视图替换空视图?
      2. 如何保存组状态并滚动列表视图的位置?
      3. 在SDK上测试:1.5r3,1.6r1

        代码:

        public class MainActivity extends ExpandableListActivity {
        
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
        
                dbHelper = new DBOpenHelper(this);
        
                rubricsDbAdapter = new RubricsDBAdapter(dbHelper);
                rubricsDbAdapter.open();
        
                itemsDbAdapter = new ItemsDBAdapter(dbHelper);
                itemsDbAdapter.open();
        
                rubricsCursor = rubricsDbAdapter.getAllItemsCursor();
                startManagingCursor(rubricsCursor);
        
                // Cache the ID column index
                rubricIdColumnIndex = rubricsCursor.getColumnIndexOrThrow(RubricsDBAdapter.KEY_ID);
        
                // Set up our adapter
                mAdapter = new MyExpandableListAdapter(rubricsCursor,
                        this,
                        android.R.layout.simple_expandable_list_item_1,
                        android.R.layout.simple_expandable_list_item_1,
                        new String[] {RubricsDBAdapter.KEY_NAME},
                        new int[] {android.R.id.text1},
                        new String[] {ItemsDBAdapter.KEY_NAME}, 
                        new int[] {android.R.id.text1});
        
                setListAdapter(mAdapter);
            }
        
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
                Intent i = new Intent(this, ItemViewActivity.class);
                i.putExtra(ItemsDBAdapter.KEY_ID, id);
                startActivity(i);
        
                return super.onChildClick(parent, v, groupPosition, childPosition, id);
            }
        
            private void updateMyData() {
                int i;
                int k;
                long rubricId;
        
                for (i = 1; i <= 5; i++) {
                    rubricId = rubricsDbAdapter.insert("rubric " + i);
                    for (k = 1; k <= 5; k++) {
                        itemsDbAdapter.insert("item " + i + "-" + k, rubricId);
                    }
                }
        
                mAdapter.notifyDataSetChanged();
            }
        
            private void deleteMyData() {
                rubricsDbAdapter.deleteAll();
                itemsDbAdapter.deleteAll();
        
                mAdapter.notifyDataSetChanged();
            }
        
            public class MyExpandableListAdapter extends SimpleCursorTreeAdapter 
            {
                public MyExpandableListAdapter(Cursor cursor, Context context, int groupLayout,
                        int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,
                        int[] childrenTo) {
                    super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
                            childrenTo);
                }
        
                @Override
                protected Cursor getChildrenCursor(Cursor notebookCursor) {
                    // Given the group, we return a cursor for all the children within that group 
                    long id = notebookCursor.getLong(rubricIdColumnIndex);
        
                    Cursor itemsCursor = itemsDbAdapter.getRubricItemsCursor(id);
                    startManagingCursor(itemsCursor);
                    return itemsCursor;
                }
        
            }
        }
        

2 个答案:

答案 0 :(得分:4)

所以答案是:

  1. 在调用adapter的notifyDataSetChanged()方法之前调用cursor.requery()。
  2. 在活动的onPause()方法中保存组状态,并在onResume()方法中恢复。

答案 1 :(得分:2)

回复:问题#2 ......

为什么不能简单地按顺序调用View.invalidateViews()和View.requestLayout()?

如果您已将适配器设置为视图,那么您不需要重新查询,是吗?通过使视图无效并请求布局,您将不会丢失视图的任何状态。

例如,在“onResume”方法中,通过调用“lv.invalidateViews()”之类的内容使列表视图无效。接下来,调用“lv.requestLayout()”。

您的“onCreate”方法仍应负责设置适配器并将适配器链接到视图。要链接适配器,请考虑使用“lv.setListAdapter()”而不是前者,以便您不会弄乱屏幕上的其他视图。