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

Android类BaseAdapter中的getItem和getItemId方法的目的是什么?,android,adapter,Android,Adapter,我对androidsdk中的方法和类适配器的用途很好奇 从描述来看,getItem似乎应该返回底层数据。因此,如果我有一个名称数组[“cat”、“dog”、“red”]并且我使用它创建了一个适配器a,那么a.getItem(1)应该返回“dog”,对吗?a.getItemId(1)应该返回什么 如果您已经在实践中使用了这些方法,您能提供一个示例吗?getItemId方法主要用于使用SQLite数据库支持的游标。它将返回位置1中项目的基础游标id字段 在您的例子中,位置1中的项没有id:我假设Ar

我对androidsdk中的方法和类适配器的用途很好奇

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


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

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

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


EDIT:实际上,它只是返回位置:在本例中,我认为这些方法是访问列表数据的更干净的方法。我不需要通过类似于
myListData.get(position)
的方式直接访问适配器对象,而只需像
adapter.get(position)
那样调用适配器即可

这同样适用于
getItemId
。通常,当我想基于列表中某个对象的唯一ID执行某个任务时,我会使用此方法。这在使用数据库时特别有用。返回的
id
可以是对数据库中某个对象的引用,然后我可以对该对象执行不同的操作(更新/删除/etc)

因此,您可以使用
adapter.getItemId(position)
而不是从原始数据对象(如
myListData.get(position).getId())访问ID

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

例如,如果列表中有两个部分(水果和糖果):如果使用了
getItem(position)
并且
position
恰好位于fruit部分中的某个项目上,您将收到与请求
getItem(position)不同的对象
带有
位置
指向糖果部分中的项目。然后,您可以在
getItemId(position)
中返回某种类型的常量ID值,该值表示
getItem(position)
返回的数据类型,或者使用
instanceof
确定您拥有的对象


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

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

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

  • 对视图本身的引用
  • 它在列表中的数字位置
  • 很长
    已附加到各个元素
这是由你来决定哪一个是你最容易处理的这三个在你的特殊情况下,但你有所有的三个选择所有的时间。可以将此
long
视为自动附加到项目的标签,只是它更简单、更容易读取

对它通常做什么的误解源于一个简单的惯例。所有适配器都必须提供
getItemId()
,即使它们实际上没有使用第三个标识。因此,按照惯例,这些适配器(包括SDK中的许多示例中的适配器或web上的所有适配器)只返回
position
,原因只有一个:它总是唯一的。尽管如此,如果适配器返回
位置
,这实际上意味着它根本不想使用此功能,因为无论如何,
位置
是已知的

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

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

我想提到的是,在实现
getItem
getItemId
之后,您可以使用和直接访问数据,而不是通过适配器。这在实现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取决于coverUrltitle字段的值,如果您在适配器上更改然后调用
notifyDataSetChanged()
,那么适配器将调用每个元素的getItemId()方法,并且只更新id已更改的数千个项目。

如果您在
getView()
中执行一些“繁重”操作,这将非常有用


顺便说一句:如果你想让它工作,你需要确保你的
hasStableIds()
方法返回false

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