SimpleCursorAdapter и ViewBinder — привязка данных к элементам ListView для извлечения по щелчку

Итак, у меня есть ListView (используя ListActivity), который я заполняю из SQLiteDatabase. Я пытаюсь прикрепить идентификатор (PK) строки к представлению, чтобы onListItemClick каждого элемента списка я мог что-то делать с этим идентификатором.

Я читал, что произвольные данные могут быть установлены в View с помощью setTag и извлечены с помощью getTag (на самом деле я еще не успешно работал с этой работой, так что это может быть проблемой). Вот урезанная версия того, что я использую (для простоты/краткости):

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();
    }       
}

ListView заполняется, и Toast действительно отображается, но это всегда "ID=null", поэтому, очевидно, идентификатор не устанавливается в ViewBinder вызове setTag (или не извлекается свойство с getTag).


person momo    schedule 05.12.2011    source источник
comment
onListItemClick, я хочу иметь возможность работать с частью произвольных данных, назначенных элементу списка (в этом примере — идентификатор (первичный ключ) строки SQLite, которая назначила данные).   -  person momo    schedule 05.12.2011


Ответы (2)


Это зависит от вашей реализации R.layout.favorite. Если у вас есть этот макет, содержит родительское представление с дочерними TextViews, например. установленный вами тег предназначен для TextView, а View v, полученный от onListItemClick(), является родительским View. Вам нужно убедиться, что вы получаете тег для того же представления, которое вы установили, используя:

    @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();      
    }    
person Mohamed_AbdAllah    schedule 05.12.2011
comment
это выглядит многообещающе. вы правы, любимый макет - это linearlayout с дочерними текстовыми представлениями. вместо того, чтобы щелкнуть дочерний элемент, есть ли способ установить тег (в ViewBinder) для родителя linearlayout вместо textview? есть ли причина, по которой ViewBinder устанавливает его в дочерний элемент вместо основного контейнера? - person momo; 05.12.2011
comment
Причина, по которой ViewBinder устанавливает его в дочерний, заключается в том, что ViewBinder запускается каждый раз, когда адаптер заполняет представление из столбцов курсора. Я думаю, вы могли бы сделать это, изменив: view.setTag(cursor.getInt(0)); на view.getParent().setTag(cursor.getInt(0)); в ViewBinder - person Mohamed_AbdAllah; 05.12.2011
comment
В итоге я использовал собственный адаптер, но предоставленная вами информация более ценна, чем просто заставить ее работать (что также делает ваш ответ) - так что большое спасибо - person momo; 05.12.2011
comment
Я разместил аналогичный вопрос здесь: stackoverflow.com/questions/ 8384757/ если хотите посмотреть - person momo; 05.12.2011

Вы, вероятно, должны получить курсор от адаптера. Таким образом, если ваш курсор будет заменен, вы все равно получите действительный курсор.

@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();
    } 

ПРИМЕЧАНИЕ: ваш адаптер должен быть объявлен как SimpleCursorAdapter, в противном случае вам следует его понизить.

person confucius    schedule 05.12.2011