Android ListView SimpleCursorAdapter TextView 和 ImageButton

Android ListView SimpleCursorAdapter TextView and ImageButton

我有一个由 SQLite 数据库 table 支持的 ListView,它在每行的列表项 XML 中显示一个歌曲标题 (TextView) 和一个按钮 (ImageButton)。我为按钮设置了一个 onClick() 事件,以对他们单击的行上的歌曲执行操作。

ListView 使用 SimpleCursorAdapter 正确显示数据库 table 中的所有内容。

这里的问题是:当我点击 ImageButton 时,它正确地调用带有参数的按钮的 onClick 事件 (View view);如何从传递给事件的视图中获取单击按钮所在行的光标行数据?我需要行 _ID 值才能对正确的歌曲进行操作。如果我可以从 object.

到达那里,我也可以访问 Class 字段中的 dbAdapter

注意:当我将 ImageButton 添加到项目列表时,如果我单击包含歌曲的行或按钮,则 onItemClickListener 不再触发。

而且,如果有更好的设计模式可以为用户提供选择 ListView 项目并对其执行操作的功能,请告诉我。我的意图是最终每行添加 2-3 个按钮,用于删除、信息、播放等。

// Load ListView with previously downloaded files
dbHelper = new DBHelper(this);

// Create Cursor holding db data
Cursor cursor = dbHelper.fetchData();

// Map db columns to view ids
String[] columns = new String[]{
        DBContract.Songs.COLUMN_NAME_NAME,
        DBContract.Songs.COLUMN_NAME_LOADED_DATETIME
};

int[] to = new int[]{
        R.id.songName,
        R.id.songDateLoaded
};

// Create the dbAdapter
dbAdapter = new SimpleCursorAdapter(this, R.layout.songs, cursor, columns, to, 0);

// Assign the adapter to the ListView
ListView listView = findViewById(R.id.songsListView);
listView.setAdapter(dbAdapter);

// Anonymous OnItemClickListener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {...

在 Mike 的坚持和耐心的帮助下,我实现了以下解决方案。

关键是在 SimpleCursorAdapter 上使用 setViewBinder(),然后将数据库行键分配给 ImageButton 的标签 属性。然后,在 XML 中定义一个 onClick() 事件,在该事件中,您现在可以从 view.getTag() 方法访问数据库行键。

// Bind the Cursor record _ID to the ImageButton Tag property;
// So when it is called, we can delete the record with the Tag property value.
dbAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
    @Override
    public boolean setViewValue(View view, Cursor cursor, int i) {
        if (view.getId() == R.id.songName) {
            final long id = cursor.getLong(cursor.getColumnIndex(DBContract.Songs._ID));
            final ImageButton delete = ((View)view.getParent()).findViewById(R.id.deleteSongButton);
            delete.setTag(id);
        }
        return false;
    }
});

public void DeleteSong(View view) {
    final long id = (long) view.getTag();
    dbHelper.RemoveSong(id);
    dbHelper.fetchSongsAndUpdateAdapter(dbAdapter);
    Toast.makeText(this, "Song removed!", Toast.LENGTH_LONG).show();
}

谢谢迈克!