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

one*_*ter 152 android adapter

我很好奇这些方法的目的getItem以及getItemIdAndroid SDK中的类Adapter.

从描述中看来,getItem应该返回基础数据.所以,如果我有一个名字数组,["cat","dog","red"]a用它创建一个适配器,那么a.getItem(1)应该返回"狗",对吗?应该a.getItemId(1)返回什么?

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

jam*_*mes 86

我将这些方法视为访问列表数据的更简洁方法.而不是直接通过像myListData.get(position)我这样的东西直接访问我的适配器对象adapter.get(position).

同样的道理getItemId.通常,当我想根据列表中对象的唯一ID执行某些任务时,我会使用此方法.这在使用数据库时特别有用.返回的id可以是对数据库中对象的引用,然后我可以对其进行不同的操作(更新/删除/等).

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

我觉得我需要使用这些方法的一个例子是在使用SeparatedListViewAdapter的项目中.此适配器可以包含多种不同类型的适配器,每种适配器代表不同类型的数据(通常).当调用getItem(position)SeparatedListViewAdapter,返回的对象可能会有所不同,具体取决于您发送它的位置"section".

例如,如果您的列表中有2个部分(水果和糖果):如果您使用getItem(position)position碰巧在水果部分中的某个项目上,则会收到getItem(position)与您请求position指向糖果中的项目时不同的对象部分.然后,您可能会返回某种常量ID值,getItemId(position)其中表示getItem(position)返回的数据类型,或用于instanceof确定您拥有的对象.

除了我刚才提到的,我从未觉得我真的需要使用这些方法

  • 对于非sql相关的适配器,getItemId还有目的吗?如果是的话,应该归还什么?位置? (7认同)

Gáb*_*bor 32

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

简单地说,Android允许您附加long到任何ListView项目,就这么简单.当系统通知您用户选择时,您会收到三个识别变量,以告诉您所选择的内容:

  • 对视图本身的引用,
  • 它在列表中的数字位置,
  • 这个long你附加到个别元素.

由您来决定在您的特定情况下哪三种最容易处理,但您有三种可供选择.将其long视为自动附加到项目的标签,只是它更简单,更容易读出.

对它通常做什么的误解源于一个简单的约定.所有适配器必须提供getItemId()即使他们实际上不使用此第三标识.因此,按照惯例,这些适配器(包括SDK中的样本中的许多适配器或网络上的所有适配器)仅仅position因为一个原因而返回:它始终是唯一的.但是,如果适配器返回position,这实际上意味着它根本不想使用此功能,因为position无论如何已知.

因此,如果您需要返回您认为合适的任何其他值,请随意执行此操作:

@Override
public long getItemId(int position) {
  return data.get(position).Id;
}
Run Code Online (Sandbox Code Playgroud)


Fem*_*emi 6

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

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

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

  • 作为安卓4.1.1的,它返回的位置:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/widget/ArrayAdapter.java #ArrayAdapter.getItemId%28int 29% (5认同)
  • 不,它返回`-1`.这是实现`assert false:"TODO"; return -1;` (2认同)

Dan*_*okh 5

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

例子 :

你有一个专辑列表:

class Album{
     String coverUrl;
     String title;
}
Run Code Online (Sandbox Code Playgroud)

getItemId是这样实现的:

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

现在您的项目 id 取决于coverUrltitle字段的值,如果您更改 then 并调用notifyDataSetChanged()您的适配器,那么适配器将调用每个元素的 getItemId() 方法并仅更新 id 已更改的项目。

如果在您的getView().

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