Actualización en vivo de ListView de Android

I have a ListView in a ListActivity that's bound to some data. I have a content provider that's providing the data.

The ListActivity gets the data by querying a content resolver:

Uri uri = Uri.parse("content://my.provider.DocumentProvider/mystuff");
contentCursor = this.getContentResolver().query(uri, null, null, null, null);

So now the activity has the cursor. It creates an adapter and attaches it to the list:

ListAdapter adapter = new DocumentListCursorAdapter(this, R.layout.main_row_layout, contentCursor, new String[] { "titleColumn" }, new int[] { titleColumnIndex  });

This works fine; the list shows the data in the cursor.

But now the content provider has new data. I want the list to update to show the new data.

The examples I've seen involve a call to the adapter's notifyDataSetChanged, but it seems to me that this breaks the separation between the content provider and the list, which is consuming the content.

Does the content provider need to know what adapters are attached to the cursor so it can call their notifyDataSetChanged method? Or is there a better way that doesn't see these two things coupled this way.

preguntado el 09 de marzo de 12 a las 14:03

I did try registering with registerContentObserver, but didn't see a change come in when the cursor changed. Should that work? -

same as slukian, plus you may need contentCursor.setNotificationUri(cr, uri); -

Who calls contentResolver.notifyChange()? The content provider wouldn't have access to call that, would it? -

+1 for the question. I have added a comment to your answer. -

3 Respuestas

Encontré la respuesta aquí:

In a nutshell, the provider calls notifyChange to indicate that the content at the URI has changed:

getContext().getContentResolver().notifyChange(uri, null);

And the ListActivity calls setNotificationUri on the cursor to register that it's interested in receiving notification of changes:

contentCursor.setNotificationUri(getContentResolver(), uri);

(Thanks njzk2 for pointing me in the right direction).

respondido 09 mar '12, 15:03

Hi, I am working on a similar problem. I have a custom BaseAdapter and I pass a Cursor obtained from the Content Provider to the Adapter. Now based on your Q & A. If I may ask, from documentation setNotificationUri Notifies the listener attached to the Resolver. How are using this to update the Listview? Are you not using ContentObserver? - Gaurav Agarval

Is the URI just a made-up value? How do I know my URI isn't accidentally the same as some other app's URI? - matt huggins

You'd use your reverse-DNS identifier at the start of the URI. com.mycompany.MyURI or something like that. That way, as long as you own the domain there will be no accidental conflicts. - stevex

asuming that ContentProvider is yours you should add cursor.setNotificationUri(getContext().getContentResolver(), uri); en tu query implementation of CP(before you return cursor) and getContext().getContentResolver().notifyChange(uri, null); in update, insert, delete ... SimpleCursorAdapter which is prolly base of your DocumentListCursorAdapter should take care about refreshing listview.

respondido 09 mar '12, 15:03

You mean, you want to update list as per data changed.
For that just try this :
when you get new cursor then just put this code instead set new adapter to list..




respondido 09 mar '12, 14:03

How do I know when to get a new cursor? The data has changed (for example, because of some network activity - new data received) and the Content Provider is aware that the data has changed. What does the content provider do to get the notification through to the ListActivity? It's easy enough to solve this if you assume the provider and the list are in the same app, but what if the content provider is connected to a list in a different process? What does the content provider do to communicate the change across to where the list is? - stevex

Do we need to do the both or adapter.notifyDatasetChanged() will update the Listview? - Gaurav Agarval

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.