Question

So I've got a ListView (using a ListActivity) that I'm populating from a SQLiteDatabase. I'm trying to attach the ID (PK) of the row to the view, so that onListItemClick of each list item, I can do stuff with that ID.

I've read that arbitrary data can be set to a View using setTag and retrieved with getTag(I haven't actually had this work successfully yet, so this may be the problem). Here's a pared down version of what I'm using (for simplicity/brevity):

public class Favorites extends ListActivity {   
    public void onCreate(Bundle savedInstanceState){        
        super.onCreate(savedInstanceState);
        FavoritesDB db = FavoritesDB.getInstance(this);     
        Cursor c = db.fetchFavorites();
        startManagingCursor(c);     
        String[] columns = new String[] { "_id" };
        int[] to = new int[] { R.id.word };         
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.favorite, c, columns, to);     
        adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
            public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
                view.setTag(cursor.getInt(0));
                return true;
            }
        });
        setListAdapter(adapter);        
    }   
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Object wordID = v.getTag();
        Toast.makeText(getBaseContext(), "ID=" + wordID, 1).show();
    }       
}

The ListView is being populated, and the Toast does show up, but it's always "ID=null", so apparently the ID isn't being set in the ViewBinder call to setTag(or isn't being retrieved property with getTag).

Was it helpful?

Solution

This depends on your implementation of R.layout.favorite. If you have this layout contains a parent view with child TextViews for e.g. the tag you set is for the TextViews while the View v received from the onListItemClick() is the parent View. You need to make sure that you receive the tag for the same view you set by using:

    @Override      
    protected void onListItemClick(ListView l, View v, int position, long id) {
    Object wordID = v.getChild(0).getTag();          
    Toast.makeText(getBaseContext(), "ID=" + wordID, 1).show();      
    }    

OTHER TIPS

You probably should get the cursor from the adapter. This way if your cursor gets replaced you are still are still getting a valid cursor.

@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
       Cursor cursor =  adapter.getCursor();
       cursor.moveToPosition(position);
       String id = cursor.getString(cursor.getColumnIndex("primary key field name in database");
       Toast.makeText(getBaseContext(), "ID=" + id, 1).show();
    } 

NOTE : your adapter must be declared as a SimpleCursorAdapter other wise you should downcast it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top