3

I'm trying to refresh a ListView that uses a ListAdapter created as a SimpleCursorAdapter.

Here is my code for creating the Cursor and ListAdapter in onCreate which populates the ListView.

tCursor = db.getAllEntries();       

ListAdapter adapter=new SimpleCursorAdapter(this,
                R.layout.row, tCursor,
                new String[] columns,
                new int[] {R.id.rowid, R.id.date});

setListAdapter(adapter);

Then, I add some data to the db in another method, but I can't figure out how to refresh the ListView. Similar questions on stackoverflow and other places mention using notifyDataSetChanged() and requery(), but neither are methods of ListAdapter or SimpleCursorAdapter.

spryan
  • 138
  • 1
  • 2
  • 7

4 Answers4

5

I'm able to get the ListView to refresh by creating a new adapter and calling setListAdapter again.

I named it adapter2 in the other method.

tCursor = db.updateQuery();       

ListAdapter adapter2=new SimpleCursorAdapter(this,
                R.layout.row, tCursor,
                columns,
                new int[] {R.id.rowid, R.id.date});

setListAdapter(adapter2);

I'm not sure why this is necessary, but it works for now. If anyone has a better solution, I'm willing to try it.

spryan
  • 138
  • 1
  • 2
  • 7
0

You can define the adapter as a class variable if it needs to be accessed from other methods in the same class. Then you can call changeCursor() to refresh the ListView.

public class mainActivity extends AppCompatActivity {
    // Define the Cursor variable here so it can be accessed from the entire class.
    private SimpleCursorAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_coordinator_layout)

        // Get the initial cursor
        Cursor tCursor = db.getAllEntries();       

        // Setup the SimpleCursorAdapter.
        adapter = new SimpleCursorAdapter(this,
            R.layout.row,
            tCursor,
            new String[] { "column1", "column2" },
            new int[] { R.id.rowid, R.id.date },
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

        // Populate the ListAdapter.
        setListAdapter(adapter);
    }

    protected void updateListView() {
        // Get an updated cursor with any changes to the database.
        Cursor updatedCursor = db.getAllEntries();

        // Update the ListAdapter.
        adapter.changeCursor(updatedCursor);
    }
}

If the list view needs to be updated from methods in another class, the adapter variable should be declared public static instead

public static SimpleCursorAdapter adapter;
Soren Stoutner
  • 1,413
  • 15
  • 21
0

In that case I recommend to go with custom Adapter, by extending the BaseAdapter class.

mmoya
  • 1,901
  • 1
  • 21
  • 30
Rohit Mandiwal
  • 10,258
  • 5
  • 70
  • 83
  • As I mentioned in the original question, notifyDataSetChanged() does not work for a ListAdapter. The error given by Eclipse says "The method notifyDataSetChanged() is undefined for the type ListAdapter". – spryan Feb 25 '11 at 04:00
  • Rewriting code that works is hopefully a last resort, but I'll take that into consideration. Thanks for trying. – spryan Feb 25 '11 at 04:31
0

The method notifyDataSetChanged comes from the SimpleCursorAdapter parent class BaseAdapter. The parent implements ListAdapter and you should be able to pass it to your ListView.

Try:

tCursor = db.getAllEntries();       

BaseAdapter adapter=new SimpleCursorAdapter(this,
            R.layout.row, tCursor,
            new String[] columns,
            new int[] {R.id.rowid, R.id.date});

setListAdapter(adapter);


Then you should be able to use notifyDataSetChanged.

Louth
  • 11,401
  • 5
  • 28
  • 37
  • 1
    I changed the type of adapter from ListAdapter to BaseAdapter as you suggested. The list still loads properly, but calling adapter.notifyDataSetChanged() doesn't refresh the ListView when I call it from another method. Am I using this incorrectly? – spryan Feb 25 '11 at 05:20