Sandy
Sandy

Reputation: 2690

Refresh ListView from ListActivity with CursorAdapter

I have a ListActivity that uses a CursorAdapter, and I can't get it to refresh. Here is some of the code I'm using:

public class ContactDetailsActivity extends ListActivity
{

    private ContactDetailsBroadcastReceiver mLvBroadcastReceiver;
    private Contact contact;


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);


        contact = (Contact)getIntent().getSerializableExtra(AwesomeApp.CONTACT_OBJECT);

        if(contact == null) {
            DataUtils.log("Starting ContactDetailsActivity with NULL contact.");
            Toast.makeText(this, getString(R.string.no_contact_selected), Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

        DataUtils.log("Starting ContactDetailsActivity with contact:" + contact.toString());
        setTitle(contact.getName());

        Cursor cursor = getContactDetailsCursor();
        startManagingCursor(cursor);

        setListAdapter(new ContactDetailsCursorAdapter(this, cursor));

        ListView lv = getListView();
        lv.setBackgroundResource(R.color.white);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {
                Toast.makeText(ContactDetailsActivity.this, "touched", Toast.LENGTH_SHORT).show();
            }
        });

        //Create broadcast receiver, to detect when a file upload has finished so we can update the pic status.
        mLvBroadcastReceiver = new ContactDetailsBroadcastReceiver();
    }

    private class ContactDetailsBroadcastReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            DataUtils.log("In BroadcastReceiver - ContactDetails");
            refreshListView();
        }
    }

My adapter basically just extends CursorAdapter in which I override newView and bindView:

public class ContactDetailsCursorAdapter extends CursorAdapter

I have a method inside ContactDetailsActivity called refreshListView() which I call in onResume(), and in the onReceive() method of my BroadcastReceiver

private void refreshListView()
{
    DataUtils.log("In ContactDetailsActivity refreshListView");
    ((ContactDetailsCursorAdapter)getListAdapter()).notifyDataSetChanged();

    this.getListView().invalidate();

    this.getListView().invalidateViews();
}

This is my getContactDetailsCursor() method:

private Cursor getContactDetailsCursor()
{
    AwesomeDbAdapter dbAdapter = AwesomeApp.getDbAdapter(this);
    Cursor c = dbAdapter.getRecentConversationsFromContact(contact.getId());
    DataUtils.log("New ContactDetails cursor has " + c.getCount() + " elements");
    return c;
}

As you can see, I've tried notifyDataSetChanged(), invalidate(), invalidateViews() and nothing seems to refresh the listview.

I'm totally out of ideas on how to get this to refresh. I'm seeing the logs and the method is being called both from onResume() and from the BroadcastReceiver's onReceive() methods.

Any pointers are appreciated!

Upvotes: 0

Views: 331

Answers (3)

Sandy
Sandy

Reputation: 2690

This is what finally worked for me. As mentioned by @Kirill Shalnov, startManagingCursor() is deprecated however it's what I need to use. To be honest it's all a bit of guesswork, but alas does what I need.

@SuppressWarnings("deprecation")
private void refreshListView()
{
    DataUtils.log("In ContactDetailsActivity refreshListView");

    ContactDetailsCursorAdapter adapter = (ContactDetailsCursorAdapter)getListAdapter();

    Cursor oldCursor = null;
    if(adapter != null) {
        oldCursor = adapter.getCursor();
    }
    Cursor newCursor = getContactDetailsCursor();

    if(oldCursor != null) {
        stopManagingCursor(oldCursor);
        oldCursor.close();
    }
    startManagingCursor(newCursor);

    adapter = null;
    setListAdapter(new ContactDetailsCursorAdapter(this, newCursor));

    ListView listView = getListView();
    listView.setBackgroundResource(R.color.white);
    listView.invalidate();
    listView.invalidateViews();
}

Upvotes: 1

Kirill Shalnov
Kirill Shalnov

Reputation: 2216

startManagingCursor(cursor);

It is deprecated way to work with cursor, you should to use Loaders, which can reload data automatically

Upvotes: 0

Rathan Kumar
Rathan Kumar

Reputation: 2577

it seems you forgot to register the receiver: Register the receiver without registering it won't fire, register that receiver like below.

Example: In OnCreate:

ContactDetailsBroadcastReceiver receiver=new ContactDetailsBroadcastReceiver();
IntentFilter filter=new IntentFilter("android.net.wifi.STATE_CHANGE")
registerReceiver(receiver, filter);

In OnDestroy:

unregisterReceiver(receiver);

Upvotes: 0

Related Questions