midnight
midnight

Reputation: 3412

Way to update UI after database change has occured

I'm developing an app based on Google IO presentation architecture using the first approach. Basically I have a Service, ContentProvider backed by SQLite DB and I also use Loaders.

I need a way to update UI when changes to my database occur. For instance a user might want to add an item into his basket. After I insert the item id into the basket table I want to update the UI. What approach should I use? I've seen very little information on ContentObserver so far. Is it the way to go?

Upvotes: 7

Views: 7588

Answers (2)

David Corsalini
David Corsalini

Reputation: 8208

In the query method of your ContentProvider attach a listener to the returned cursor:

 Cursor cursor = queryBuilder.query(dbConnection, projection, selection, selectionArgs, null, null, sortOrder);
 cursor.setNotificationUri(getContext().getContentResolver(), uri);

Then in your insert/update/delete methods use code like this:

 final long objectId = dbConnection.insertOrThrow(ObjectTable.TABLE_NAME, null, values);
 final Uri newObjectUri = ContentUris.withAppendedId(OBJECT_CONTENT_URI, objectId );
 getContext().getContentResolver().notifyChange(newObjectUri , null);

Your CursorLoader will be notified and the OnLoadFinished(Loader, Cursor) will be called again.

If you're not using a Loader, the ContentObserver is the way to go, with a few lines of code you are notified on db changes (but you will need to requery manually).

  private ContentObserver objectObserver = new ContentObserver(new Handler()) {
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        restartObjectLoader();
    }
};

Remember to call in onResume():

 getContentResolver().registerContentObserver(ObjectProvider.OBJECT_CONTENT_URI, false, objectObserver);

and in onPause():

 getContentResolver().unregisterContentObserver(objectObserver);

Update: UI Changes This is a larger topic because it depends on the Adapter you use to fill the ListView or RecyclerView.

CursorAdapter In onLoadFinished(Loader loader, Cursor data)

 mAdapter.swapCursor(data);

ArrayAdapter In onLoadFinished(Loader loader, Cursor data)

 Object[] objects = transformCursorToArray(data); //you need to write this method
 mAdapter.setObjects(objects); //You need to wrie this method in your implementation on the adapter
 mAdapter.notifyDataSetChange();

RecyclerView.Adapter In onLoadFinished(Loader loader, Cursor data)

 Object[] objects = transformCursorToArray(data); //you need to write this method
 //Here you have more mAdapter.notify....()

Read from here for different way to notify the RecyclerView.Adapter.

Upvotes: 10

Bahadir Gul
Bahadir Gul

Reputation: 150

If you are using a list, you can fill adapter again and set it to your list. Or try to inform data set change.

Upvotes: 2

Related Questions