2

I am querying the ContactsContract.Data table in Android using a ListView to display the data.

Is there a way to modify the data returned from the Content Provider before it gets displayed?

Here is a concrete example:

I can query ContactsContract.Data for the STARRED column which will return a '0' or '1', but what about the case where I would like to instead convert the '0' to 'not starred' and the '1' to 'starred'

Here is my existing code:

 private void populateList() {
// Start with the cursor
    Cursor cursor = getContacts();
    // Then the adapter
    String[] fields = new String [] {
            ContactsContract.Data.DISPLAY_NAME,
            ContactsContract.Data.CONTACT_STATUS,
                    // WOULD LIKE THIS FIELD TO BE MODIFIED
            ContactsContract.Data.STARRED
    };
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            R.layout.aa_list_activity_row_sjp,
            //android.R.layout.simple_list_item_multiple_choice,
            cursor,
            fields,
            new int [] {
                R.id.rowText1,
                R.id.rowText2,
                R.id.rowText3
                });
    // end with "setListAdapter"
    setListAdapter(adapter);
}

private Cursor getContacts() {
    // Setup the query and return a cursor
    Uri uri = ContactsContract.Contacts.CONTENT_URI;
    String [] projection = new String [] {
        ContactsContract.Contacts._ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Contacts.CONTACT_STATUS,
        ContactsContract.Contacts.STARRED
    };
    String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
    String [] selectionArgs = null;
    String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";

    return managedQuery(uri, projection, selection, selectionArgs, sortOrder);
}

I am not sure if it is possible, but rather than inserting the value of the STARRED column directly into my View I would like to first do some conditional editing of the column value.

Any Suggestions?

Thank you very much, Steve

Steven James
  • 115
  • 2
  • 10

2 Answers2

1

You could try subclassing SimpleCursorAdapter and implement the method

public void setViewText(TextView v, String text) {
    if (v.getId() == R.id.rowText3) {
        text = "0".equals(text) ? "not starred" : "starred";
    }
    v.setText(text);
}
djg
  • 1,283
  • 9
  • 6
  • Awesome, this works great and I was banging my head against the wall for quite some time now. Also it refocused my search allowing me to discover SimpleCursorAdapter.ViewBinder - I would vote this up if I had the rep :) – Steven James Mar 04 '11 at 03:19
1

djg inspired me and after some more research I found this solution alluded to in another thread:

You could set a custom SimpleCursorAdapter.ViewBinder:

I like this solution because you do not need to create another class if you use an anonymous implementation.

In my specific case I would insert the following code block after instantiating my SimpleCursorAdapter and right before the call to setListAdapter(adapter);

The new code:

adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
  @Override
  public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
    if (columnIndex == 3) {
      ((TextView) view).setText(cursor.getString(columnIndex).equals("1") ? "starred" : "not starred");
      return true;
    }
    return false;
  }
});
Community
  • 1
  • 1
Steven James
  • 115
  • 2
  • 10