Android 类 BaseAdapter 中 getItem 和 getItemId 方法的意图是什么?

我很好奇 Android SDK 中 Adapter 类中的 getItemgetItemId方法的用途。

从描述来看,似乎 getItem应该返回基础数据。因此,如果我有一个名称 ["cat","dog","red"]的数组,并且我使用它创建了一个适配器 a,那么 a.getItem(1)应该返回“ dog”,对吗?a.getItemId(1)应该返回什么?

如果您已经在实践中使用了这些方法,您能提供一个例子吗?

60332 次浏览

getItemId方法主要用于处理由 SQLite 数据库支持的游标。它将返回位置1中的项的基础游标的 id 字段。

在您的示例中,位置1中的项没有 id: 我假设 ArrayAdapter 的实现只返回 -1或0。

编辑: 实际上,它只返回位置: 在本例中为 1

我认为这些方法是访问列表数据的一种更干净的方法。我可以简单地调用适配器(如 adapter.get(position)) ,而不是通过类似 myListData.get(position)的东西直接访问适配器对象。

getItemId也是如此。通常,当我想根据列表中对象的唯一 ID 执行某个任务时,我会使用此方法。这在使用数据库时特别有用。返回的 id可以是对数据库中对象的引用,然后我可以对其执行不同的操作(update/delete/etc)。

因此,可以使用 adapter.getItemId(position)代替从原始数据对象(如 myListData.get(position).getId())访问 ID。

我觉得我需要使用这些方法的一个例子是在一个使用 分离的 ListViewAdapter的项目中。此适配器可以包含多种不同类型的适配器,每个适配器表示不同类型的数据(通常)。当在 SeparatedListViewAdapter上调用 getItem(position)时,返回的对象可能会有所不同,这取决于您发送它的位置是哪个“部分”。

例如,如果你在你的列表中有两个部分(水果和糖果) : 如果你使用 getItem(position)position碰巧是在 水果部分的一个项目,你会收到一个不同的对象,如果你请求 getItem(position)position指向一个项目在 糖果部分。然后,您可以在 getItemId(position)中返回某种常量 ID 值,它表示 getItem(position)返回的数据类型,或者使用 instanceof来确定您拥有的对象。

除了上面提到的,我从来没有感觉到我真的需要使用这些方法

好吧,看来这个问题可以用一种更简单、更直接的方式来回答... ... : -)

简单地说,Android 允许你将 long附加到任何 ListView项目上,就是这么简单。当系统通知您用户选择时,您将收到 标识变量,告诉您选择了什么:

  • 对视图本身的引用,
  • 它在列表中的数字位置,
  • 这个 long你连接到单独的元素。

在你的特殊情况下,这三者中的哪一个对你来说是最容易处理的取决于你自己,但是你一直都可以从这三者中进行选择。把这个 long想象成一个自动附加到项目上的标签,只不过它更简单,更容易读出来。

关于它通常做什么的误解源于一个简单的约定。所有适配器都必须提供 getItemId(),即使它们实际上并没有使用这第三个标识。因此,按照惯例,这些适配器(包括 SDK 中的许多示例或整个 Web 中的许多示例)只返回 position,原因只有一个: 它始终是唯一的。不过,如果适配器返回 position,这实际上意味着 它根本就不想用这个功能,,因为 position已经知道了。

因此,如果您需要返回您认为合适的任何其他值,请随时这样做:

@Override
public long getItemId(int position) {
return data.get(position).Id;
}

我想提到的是,在实现 getItemgetItemId之后,您可以使用 GetItemAtpositionGetItemIdAtposition直接访问您的数据,而不是通过适配器。这在实现 onClick 侦听器时可能特别有用。

如果正确实现 getItemId,那么它可能非常有用。

例如:

你有一个专辑列表:

class Album{
String coverUrl;
String title;
}

然后像这样实现 getItemId:

@Override
public long getItemId(int position){
Album album = mListOfAlbums.get(position);
return (album.coverUrl + album.title).hashcode();
}

现在,您的项目 id 依赖于 Cover Url书名字段的值,如果您更改了该值并在适配器上调用 notifyDataSetChanged(),那么适配器将调用每个元素和 只更新标识已更改的房屋项目。的 getItemId ()方法

这是非常有用的,如果正在做一些“重”的操作在您的 getView()

顺便说一句: 如果你想这个工作,你需要确保你的 hasStableIds()方法返回假;

getItemgetItemId是少数几种主要设计用于将数据与列表中的项目连接起来的方法。对于 getItem,您可以传递将附加到列表中的项的任何对象。通常人们返回 nullgetItemId是您可以用列表中的相同项目附加的任何唯一 long值。人们通常返回列表中的位置。

有什么用。因为这些值绑定到列表中的项,所以可以在用户单击该项时提取它们。这些值可以通过 AdapterView方法访问。

// template class to create list item objects
class MyListItem{
public String name;
public long dbId;


public MyListItem(String name, long dbId){
this.name = name;
this.dbId = dbId;
}
}


///////////////////////////////////////////////////////////


// create ArrayList of MyListItem
ArrayList<MyListItem> myListItems = new ArrayList<MyListItem>(10);


// override BaseAdapter methods
@Override
public Object getItem(int position) {
// return actual object <MyListItem>
// which will be available with item in ListView
return myListItems.get(position);
}


@Override
public long getItemId(int position) {
// return id of database document object
return myListItems.get(position).dbId;
}


///////////////////////////////////////////////////////////


// on list item click, get name and database document id
my_list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {


// extract item data
MyListItem selectedItem = (MyListItem)parent.getItemAtPosition(position);
System.out.println("Your name is : " + selectedItem.name);


// extract database ref id
long dbId = id;


// or you could also use
long dbId = parent.getItemIdAtPosition(position);
}
});

如果适配器 ui 根据位置更改,请使用以下两种方法

@Override
public long getItemId(int position) {
return position;
}


@Override
public int getItemViewType(int position) {
return position;
}