Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 250
midnight Avatar asked Dec 05 '14 08:12

midnight


1 Answers

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.

like image 120
David Corsalini Avatar answered Sep 23 '22 18:09

David Corsalini