Listview with CursorAdapter
Asked Answered
O

2

8

I'm developing an application which displays Phone contacts with CursorAdapter. When I run it, I faced with a list view which repeated just one contact as bellow ("david" is one of my contacts, just repeated in listview)

david 017224860

david 017224860

david 017224860

david 017224860

david 017224860

david 017224860 .

.

.

.

My activity looks like

public class Contacts extends Activity {    
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.contacts);

    Cursor cursor = getContentResolver()
        .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
               null, null, null, null);

    startManagingCursor(cursor);

    ContactCursorAdapterCT adapter= new ContactCursorAdapterCT(Contacts.this, cursor);
     ListView contactLV = (ListView) findViewById(R.id.listviewblcontactsDB);

    contactLV.setAdapter(adapter);

And my cursorAdapter looks like:

public class ContactCursorAdapterCT extends CursorAdapter {
       public ContactCursorAdapterCT(Context context, Cursor c) {
    super(context, c);
    // TODO Auto-generated constructor stub
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    while (cursor.moveToNext()) {

        TextView name = (TextView)view.findViewById(R.id.blacklistDB1);               
          name.setText(cursor.getString(cursor.getColumnIndex
          (ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));

        TextView phone = (TextView)view.findViewById(R.id.blacklistDB2); 
          phone.setText(cursor.getString(cursor.getColumnIndex
          (ContactsContract.CommonDataKinds.Phone.NUMBER)));

    }
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
    // TODO Auto-generated method stub

    LayoutInflater inflater = LayoutInflater.from(context);

    View v = inflater.inflate(R.layout.lv, parent, false);
            bindView(v, context, cursor);
           return v;
}
Orgell answered 29/11, 2012 at 17:12 Comment(0)
A
26

I noticed a few points:

  1. A CursorAdapter moves the Cursor for you, take out your call to cursor.moveToNext().
  2. The adapter's getView() calls newView() and bindView() on it's own; you shouldn't call these methods yourself.
  3. You should watch the Android developer's lectures at Google IO to learn tips and tricks about speeding up your adapter. Tips like:
    • Using a ViewHolder, rather than calling findViewById() repeatedly.
    • Saving the indices of your Cursor, rather than calling getColumnIndex() repeatedly.
    • Fetching the LayoutInflater once and keeping a local reference.
Antitoxic answered 29/11, 2012 at 17:16 Comment(3)
This answer suggests that the ViewHolder tip is not necessary with a CursorAdapter?Oogonium
Thank you for sharing "The world of ListView" with us! I almost started implementing something really bad. I'm going to celebrate the hours I got back.Lichter
Link to Google IO listview presentation is broken, video hereOak
F
4

Also, I suggest you switch from using CursorManager to using CursorLoader. This is documented in the Android API guide, under Loaders. A specific example that you might find useful is here.

A Cursor Adapter "connects" a Cursor to a ListView. The Cursor is a data view of the data, and the ListView is a UI view of the same data. You don't need to program anything to make the ListView stay in sync with the Cursor, that's all handled automatically.

You do need to tell the ListView which columns in the Cursor it should display, See the documentation for the SimpleCursorAdapter class. I usually use that class unless I have to modify the data as I move it from the Cursor to the ListView.

Florentinaflorentine answered 29/11, 2012 at 21:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.