从绑定了 SimpleCursorAdapter 的 ListView 中获取所选项目

问题描述:

我是 Android 开发的新手...来自 iPhone 和 .Net 背景.我见过与这个非常相似的问题,但没有一个涉及 SimpleCursorAdapter.

I'm brand new to Android development... coming from iPhone and .Net background. I've seen very similar questions to this one, but none of them dealt with the SimpleCursorAdapter.

我有一个基本的 ListActivity,它使用 Cursor 将数据从 SQLite 查询绑定到我的 ListView:

I have a basic ListActivity which uses a Cursor to bind data from a SQLite query to my ListView:

ListAdapter adapter = new SimpleCursorAdapter(
        this, 
        android.R.layout.simple_list_item_1,  
        c,        
        new String[] {"name"},   
        new int[] {android.R.id.text1}); 

setListAdapter(adapter);

然后当一个项目被点击时:

Then when an item is clicked:

public void onListItemClick(ListView l, View v, int position, long id) {

    super.onListItemClick(l, v, position,  id);

    //Difference between this:
    Cursor c = (cursor)l.getItemAtPosition(position);
    //and this??
    Cursor c = (Cursor)l.getAdapter().getItem(position);

    int categoryId = c.getInt(0);
}

这是获取所选元素的 id 的正确方法吗?这看起来很奇怪,因为我认为在关闭数据库后(这是在我绑定之后)我无法使用我的游标.当我似乎无法找到从该 id 中获取实际项目的方法时,传入的 id 有什么意义?另外,我不明白为什么 getItemAtPosition() 会返回一个游标……游标绑定到整个列表;不只是一排.最后,如果这是正确的,那么显示的两种获取光标的方式有区别吗?谢谢.

Is this the proper way to get the id of the element that was selected? It seems strange, because I wouldn't think I could use my cursor after the database is closed (which is is after I bind). What is the point of the id passed in, when I can't seem to find a way of getting the actual item from that id? Also, I don't understand why the getItemAtPosition() would return a cursor... the cursor is bound to the entire list; not just one row. Finally, if this is correct, is there a difference between the two ways shown of getting the cursor? Thanks.

那么几点:在你获取游标之后,你想要调用startManagingCursor.这将游标的生命周期与 Activity 的生命周期联系起来(因此当 Activity 被销毁时,游标会被关闭/清理).

So a couple of points: after you fetch the cursor, you want to call startManagingCursor. This ties the cursor's lifecycle with Activity's lifecycle (so when the Activity gets destroyed the cursor gets closed/cleaned up).

startManagingCursor(c);
ListAdapter adapter = new SimpleCursorAdapter(
        this, 
        android.R.layout.simple_list_item_1,  
        c,        
        new String[] {"name"},   
        new int[] {android.R.id.text1}); 
setListAdapter(adapter);

此外,数据库并未关闭,Cursor 通常保持与 DB 的实时连接(因此 ListView 可以滚动并执行可能需要将来访问 Cursor 内容的那种性质的事情.

Also, the database isn't closed, the Cursor typically keeps a live connection to the DB (so the ListView can scroll and do things of that nature that may require future access to the Cursor's contents.

对于您的核心问题,在 onListItemClick 中最简单的方法是:

To your core question, the easiest way to do it in onListItemClick is this:

Cursor c = ((SimpleCursorAdapter)l.getAdapter()).getCursor();
c.moveToPosition(position);

然后您可以使用 c.getLong(0) 来获取 id(假设您获取 id 列作为第一列,这通常是这种情况).但是,请注意,id 是作为签名的一部分传入的(请参阅 public void onListItemClick(ListView l, View v, int position, long id) 中的最后一个参数),因此您真的没有需要再次获取它(但如果你想烧掉周期,你当然可以).要访问其他列,您可以执行相同的操作,只需更改列索引即可.

You can then use the c.getLong(0) to get the id (assuming you fetched the id column as the first column which is generally the case). However, note that the id is passed in as part of the signature (see the last argument in public void onListItemClick(ListView l, View v, int position, long id)) so you really don't need to fetch it again (but you certainly can if you want to burn the cycles). For accessing other columns you can do the same thing, just change the column index.

希望有所帮助.