Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update expandable list view when adapter's data changes

Tags:

java

android

I have an activity that extends ExpandableListActivity. I use SimpleCursorTreeAdapter to fill ExpandableListView. My layout contains list view and empty view. On app start ExpandableListActivity automatically chooses the right view to display.

My steps:

  1. App starts, there is no data. (empty view on the screen)
  2. Insert some data into db.
  3. Call adapter.notifyDataSetChanged(); But empty view is still on the screen and there is no any item in my list view.

Then I restart app:

  1. List view appears. I expand all groups and scroll to the bottom.
  2. I click on the item in the list. New activity appears.
  3. Click back button. All groups are collapsed and we are at the top of the screen. Scroll position and expanded groups are not remembered.
  4. Delete all data from db and call adapter.notifyDataSetChanged();
  5. Child views have disappeared, but top-level groups are still visible.

Questions:

  1. What can I do to replace empty view with list view?
  2. What can I do to do to save state of groups and scroll position of the list view?

Tested on SDKs: 1.5r3, 1.6r1

Code:

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;
        }

    }
}
like image 567
Evgeny Shurakov Avatar asked Sep 23 '09 04:09

Evgeny Shurakov


1 Answers

So, the answer is:

  1. Call cursor.requery() before calling adapter's notifyDataSetChanged() method.
  2. Save groups state in activity's onPause() method and restore in onResume() method.
like image 188
Evgeny Shurakov Avatar answered Oct 05 '22 05:10

Evgeny Shurakov