Attend XDA's Second Annual Developer Conference, XDA:DevCon 2014!
5,740,354 Members 44,135 Now Online
XDA Developers Android and Mobile Development Forum

Dynamically refresh ListView with CursorAdapter

Tip us?
 
djolec987
Old
(Last edited by djolec987; 9th April 2014 at 01:56 AM.)
#1  
Junior Member - OP
Thanks Meter 0
Posts: 1
Join Date: Apr 2014
Default Dynamically refresh ListView with CursorAdapter

Hi everyone,
First of all, I'd like to apologize if I'm posting this in a wrong place... This is my first post, I'm still getting familiar with this forum.
I would also like to apologize for the lengthy post.

The title, to a certain extent, reflects what my problem is, but to clarify:

I'm learning Android, so I'm making a simple SMS app for practice.
In it, I have a database which has tables for sent messages, received messages and contacts. I have 3 separate activities (which do NOT extend ListActivity) which show lists for sent messages, received messages and contacts, respectively. The lists are populated through CursorAdapter.

Let's consider the activity for contacts...
In it I have list (ListView) which displays contacts (each list element displays name and phone number). Below the list I have a "Add Contact" button. When I click the button a dialog pops up and shows the form for adding new contact. The buttons in the dialog preform all the database operations.
Similarly, when I click some item in the ListView, another dialog pops up. That dialog has buttons for "Send SMS", "Edit" and "Delete" contact. Again, the buttons do all the work with the database.

The trouble:

My trouble is... When I add a new contact, or delete one (after both operations their dialogs dismiss), the ListView is not refreshed.
In order to see the refreshed list I need to close the activity and start it again.
I googled and googled this for 3 days now, and all the answers I found say that I need to call
Code:
Select Code
adapter.notifyDataSetChanged
and
Code:
Select Code
adapter.changeCursor
but that doesn't do the trick.

I'll now post the relevant code with the two methods mentioned above. I placed them where i thought they should be, but this doesn't work.
So, I humbly beg someone to guide me through this ordeal.

Many thanks in advanced!

Here comes the code:

The Adapter:

Code:
Select Code
public class AdapterContactListView extends CursorAdapter {	
	
	private MyDatabaseHelper mdbh;
	private LayoutInflater myLayoutInflater;
	
	public AdapterContactListView(Context context, Cursor c, int flags) {
		super(context, c, flags);
		mdbh = MyDatabaseHelper.getMyDatabaseHelper(context);
		myLayoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);		
	}	
	
	@Override
	public void bindView(View view, Context context, Cursor cursor) {
		// TODO Auto-generated method stub
		TextView fullNameTV = (TextView)view.findViewById(R.id.contactElementNameTV);
		TextView phoneNumberTV = (TextView)view.findViewById(R.id.contactElementNumberTV);
		String fullName = cursor.getString(cursor.getColumnIndex(mdbh.getContactFirstName()));
		fullName = fullName.concat(" ");
		fullName = fullName.concat(cursor.getString(cursor.getColumnIndex(mdbh.getContactLastName())));
		String phoneNumber = cursor.getString(cursor.getColumnIndex(mdbh.getContactPhoneNumber()));
		fullNameTV.setText(fullName);
		phoneNumberTV.setText(phoneNumber);		
	}
	@Override
	public View newView(Context context, Cursor cursor, ViewGroup parent) {
		// TODO Auto-generated method stub
		return myLayoutInflater.inflate(R.layout.contact_element, parent, false);
	}
}

And the Activity:

Code:
Select Code
public class ContactsActivity extends Activity {
	
	
	private MyUtilities myUtilities;
	private MyDatabaseHelper mdbh;
	private AdapterContactListView contactsAdapter;
	private ListView contactsListView;	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_contacts);
		mdbh = MyDatabaseHelper.getMyDatabaseHelper(this);
		myUtilities = new MyUtilities(this);	
		contactsAdapter = new AdapterContactListView(this,mdbh.getContactsCursor(),CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
		contactsListView = (ListView)findViewById(R.id.contactActivityLV);
		contactsListView.setAdapter(contactsAdapter);
		contactsListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position,	long id) {
				// TODO Auto-generated method stub
				TextView phoneNumberTV = (TextView)view.findViewById(R.id.contactElementNumberTV);				
				String phoneNumber = phoneNumberTV.getText().toString();
				Contact contact = mdbh.getContactFromPhoneNumber(phoneNumber);				
				Dialog d = myUtilities.createSelectedContactOptionsDialog(contact);
				d.show();
				contactsAdapter.changeCursor(mdbh.getContactsCursor());
				contactsAdapter.notifyDataSetChanged();
			}
		});
	}

	public void addContact(View view) {
		Dialog d = myUtilities.createAddContactDialog();
		d.show();
		contactsAdapter.changeCursor(mdbh.getContactsCursor());
		contactsAdapter.notifyDataSetChanged();
	}
}
 
deanwray
Old
#2  
deanwray's Avatar
Senior Member
Thanks Meter 413
Posts: 1,098
Join Date: Apr 2006

 
DONATE TO ME
Quote:
Originally Posted by djolec987 View Post
Hi everyone,
Well notifyDatasetChanged only informs the adapter that the backing interface has new data... but your backing it with a cursor... so in your case it would just cause getView/bindView to be called for all current visible items, thus fire a query at the cursor. I think the cursor will cache the data so it's really a reload on the cursor data and then an adapter notify call you want... If you use loader (depending on target api version) then it should do most of this for you. As it stands if you want to do it manually make sure the cursor is a new cursor of the database that has changed.

(typed in a rush)
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes