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
。
我想提到的是,在实现getItem
和getItemId
您可以使用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取决于coverUrl和title字段的值,如果您更改并在您的适配器上调用notifyDataSetChanged()
,则适配器将调用每个元素的getItemId()方法,并仅更新id已更改的thouse项目。
如果在getView()
中执行一些“重”操作,这是非常有用的。
顺便说一句:如果你想这个工作,你需要确保你的hasStableIds()
方法返回false;
getItem
或getItemId
是主要devise用于附加列表中的项目数据的方法。 在getItem
情况下,您可以传递任何将附加到列表中的项目的对象。 通常人们返回null
。 getItemId
是您可以使用列表中的相同项目附加的任何唯一的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); } });