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

我对Android SDK中Adapter类中getItem和getItemId方法的用途感到好奇。

从描述中看来,getItem应该返回基础数据。 所以,如果我有一个名称[“猫”,“狗”,“红”]的数组,我使用它创build一个适配器,然后a.getItem(1)应该返回“狗”,正确的? a.getItemId(1)应该返回什么?

如果你在实践中使用了这些方法,你能举一个例子吗?

我将这些方法看作是访问我的列表数据的一种更简洁的方法。 而不是通过像myListData.get(position)东西直接访问我的适配器对象,我可以简单地调用像adapter.get(position)的适配器。

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

因此,不用像myListData.get(position).getId()那样访问原始数据对象中的ID,您可以使用adapter.getItemId(position)

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

例如,如果您的列表中有两个部分(水果和糖果):如果您使用getItem(position)并且恰好位于水果部分的某个项目上,则会收到与请求getItem(position)position指向糖果部分中的项目。 然后你可以在getItemId(position)返回某种常量ID值,它表示返回什么样的数据getItem(position) ,或者使用instanceof来确定你拥有什么对象。

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

那么,这个问题似乎可以用一个更简单,更直接的方式来回答…… 🙂

简单地说,Android允许你将一个long连接到任何ListView项目,这很简单。 当系统通知您用户select时,您会收到三个标识variables,以告诉您所选的内容:

  • 对视图本身的引用,
  • 它在列表中的数字位置,
  • 这个long你依附于个人元素。

这是由你决定哪三个是最容易处理你的具体情况,但你有三个可以select的所有时间。 想象一下, long标签自动附加到物品上,只需简单易读即可。

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

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

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

getItemId方法在很大程度上被devise为与由SQLite数据库支持的游标一起工作。 它将返回位置1中项目的底层游标的ID字段。

在你的情况下,没有位置1的项目ID:我假设ArrayAdapter的实现只是返回-1或0。

编辑:实际上,它只是返回位置:在这种情况下1

我想提到的是,在实现getItemgetItemId您可以使用ListView.getItemAtPosition和ListView.getItemIdAtPosition直接访问您的数据,而不是通过适配器。 在实现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已更改的thouse项目。

如果在getView()中执行一些“重”操作,这是非常有用的。

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

getItemgetItemId是主要devise用于附加列表中的项目数据的方法。 在getItem情况下,您可以传递任何将附加到列表中的项目的对象。 通常人们返回nullgetItemId是您可以使用列表中的相同项目附加的任何唯一的long getItemId值。 人们通常会返回列表中的位置。

什么用途。 那么,因为这些值绑定到列表中的项目,您可以提取它们时,用户单击该项目。 这些值可以通过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); } });