我很好奇Android SDK中类Adapter中方法getItem
和getItemId
的用途。
从描述中,似乎getItem
应返回基础数据。所以,如果我有一个名为["cat","dog","red"]
的数组,并且我使用它创建了一个适配器 a
,那么 a.getItem(1)
应该返回“狗“,对吗? a.getItemId(1)
应该返回什么?
如果您在实践中使用了这些方法,可以提供一个示例吗?
答案 0 :(得分:82)
我认为这些方法是访问列表数据的更简洁方法。而不是通过类似myListData.get(position)
之类的东西直接访问我的适配器对象,我可以像adapter.get(position)
一样调用适配器。
getItemId
也是如此。通常,当我想根据列表中对象的唯一ID执行某些任务时,我会使用此方法。这在使用数据库时特别有用。返回的id
可以是对数据库中对象的引用,然后我可以对其进行不同的操作(更新/删除/等)。
因此,您可以使用myListData.get(position).getId()
而不是像adapter.getItemId(position)
这样的原始数据对象访问ID。
我觉得我需要使用这些方法的一个例子是使用SeparatedListViewAdapter的项目。此适配器可以包含多种不同类型的适配器,每种适配器代表不同类型的数据(通常)。在getItem(position)
上调用SeparatedListViewAdapter
时,返回的对象可能会有所不同,具体取决于您发送该位置的“部分”。
例如,如果您的列表中包含2个部分(水果和糖果):如果您使用getItem(position)
并且position
恰好位于水果中的项目上部分,您会收到一个不同的对象,而不是您请求getItem(position)
position
指向糖果部分中的项目。然后,您可以在getItemId(position)
中返回某种常量ID值,该值代表getItem(position)
返回的数据类型,或使用instanceof
来确定您拥有的对象。
除了我所提到的,我从未觉得我真的需要使用这些方法
答案 1 :(得分:30)
嗯,似乎这个问题可以用更简单,更直接的方式回答......: - )
简单地说,Android允许您将long
附加到任何ListView
项目,就这么简单。当系统通知您用户选择时,您会收到三个标识变量,以告诉您所选内容:
long
您附加到各个元素。由您自行决定在您的特定情况下哪三种最容易处理,但您有三种可供选择。将此long
视为自动附加到项目的标记,只是它更简单,更容易读出。
对它通常做什么的误解源于一个简单的约定。所有适配器都必须提供getItemId()
,即使它们实际上并未使用此第三个标识。因此,按照惯例,这些适配器(包括SDK中的样本中的许多适配器或网络上的所有适配器)只返回position
,原因只有一个:它始终是唯一的。尽管如此,如果适配器返回position
,这实际上意味着它根本不想使用此功能,因为position
已知,无论如何。
因此,如果您需要返回您认为合适的任何其他值,请随时执行此操作:
@Override
public long getItemId(int position) {
return data.get(position).Id;
}
答案 2 :(得分:5)
getItemId
方法主要用于处理由SQLite数据库支持的游标。它将返回位置1中项目的基础光标的id字段。
在你的情况下,位置1中的项目没有id:我假设ArrayAdapter的实现只返回-1或0。
编辑:实际上,它只返回位置:在这种情况下1
。
答案 3 :(得分:4)
我想提一下,在实施getItem
和getItemId
后,您可以使用ListView.getItemAtPosition和ListView.getItemIdAtPosition直接访问您的数据,而不是通过适配器。在实现onClick侦听器时,这可能特别有用。
答案 4 :(得分:3)
如果您正确实施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取决于 coverUrl 和标题字段的值,如果您更改然后在适配器上调用notifyDataSetChanged()
,则适配器将调用每个元素的getItemId()方法,仅更新id已更改的项目。
如果您在getView()
中执行某些“繁重”操作,这非常有用。
顺便说一句:如果你希望这个工作,你需要确保你的hasStableIds()
方法返回false;
答案 5 :(得分:1)
getItem
或getItemId
是一些主要用于附加数据与列表中的项目的方法。如果是getItem
,您可以传递将附加到列表中项目的任何对象。通常人们会返回null
。 getItemId
是您可以使用列表中的相同项附加的任何唯一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);
}
});