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

发布于 2024-11-24 08:47:50 字数 606 浏览 1 评论 0原文

我很好奇这些方法的目的 getItemgetItemId

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

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

I'm curious about the purpose of the methods getItem and getItemId in the class Adapter in the Android SDK.

From the description, it seems that getItem should return the underlying data. So, if I have an array of names ["cat","dog","red"] and I create an adapter a using that, then a.getItem(1) should return "dog", correct? What should a.getItemId(1) return?

If you've made use of these methods in practice, could you provide an example?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

攀登最高峰 2024-12-01 08:47:50

我认为这些方法是访问列表数据的更简洁的方法。我可以简单地调用像 adapter.get(position) 这样的适配器,而不是通过类似 myListData.get(position) 的方式直接访问我的适配器对象。

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

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

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

例如,如果您的列表中有 2 个部分(水果和糖果):如果您使用 getItem(position) 并且 position 恰好位于 fruit 部分,您将收到一个与您请求 getItem(position) 时不同的对象,其中 position 指向 candy部分。然后,您可能会在 getItemId(position) 中返回某种常量 ID 值,该值表示 getItem(position) 返回的数据类型,或者使用 instanceof code> 来确定您拥有什么对象。

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

I see these methods as a cleaner approach to accessing my list's data. Instead of directly accessing my adapter object via something like myListData.get(position) i can simply call the adapter like adapter.get(position).

The same goes for getItemId. Usually I would use this method when I want to execute some task based on the unique ID of an object in the list. This is especially useful when working with a database. The returned id could be a reference to an object in the database which I then could perform different operations on(update/delete/etc).

So instead of accessing the ID from the raw data object like myListData.get(position).getId() you can use adapter.getItemId(position).

One example of where i've felt like I needed to use these methods was in a project using the SeparatedListViewAdapter. This adapter can contain multiple different kinds of adapters, each representing data of a different type(typically). When calling getItem(position) on the SeparatedListViewAdapter, the object returned may be different depending on which "section" the position is that you send it.

For example, if you had 2 sections in your list(fruit and candy): If you used getItem(position) and position happened to be on an item in the fruit section, you would receive a different object than if you requested getItem(position) with position pointing to an item in the candy section. You might then return some sort of constant ID value in getItemId(position) which represents what kind of data getItem(position) is returning, or use instanceof to determine what object you have.

Other than what I've mentioned, I've never felt like I really needed to use these methods

不再见 2024-12-01 08:47:50

嗯,看来这个问题可以用更简单直接的方式来回答...:-)

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

  • 对视图本身的引用、
  • 它在列表中的数字位置、
  • 这个long 您附加到各个元素。

您可以根据自己的具体情况来决定这三者中哪一个最容易处理,但您始终可以从这三者中进行选择。可以将这个 long 视为自动附加到项目上的标签,只是它更简单、更容易读出。

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

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

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

Well, it seems that this question could be answered in a simpler and more straightforward way... :-)

Simply put, Android allows you to attach a long to any ListView item, it's that simple. When the system notifies you of the user selection, you receive three identifying variables to tell you what was selected:

  • a reference to the view itself,
  • its numeric position in the list,
  • this long you attached to the individual elements.

It's up to you to decide which of these three is the easiest for you to handle in your particular case but you have all three to choose from all the time. Think of this long as a tag automatically attached to the item, only that it's even simpler and easier to read out.

The misunderstanding about what it usually does stems from a simple convention. All adapters have to provide a getItemId() even if they don't actually use this third identification. So, by convention, those adapters (including many in samples in the SDK or all around the web) simply return position for a single reason: it's always unique. Still, if an adapter returns position, this really means it doesn't want to use this feature at all, since position is already known, anyway.

So, if you need to return any other value you see fit, feel free to do so:

@Override
public long getItemId(int position) {
  return data.get(position).Id;
}
你爱我像她 2024-12-01 08:47:50

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

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

编辑:实际上,它只是返回位置:在本例中为 1

The getItemId method is largely designed to work with Cursors that are backed by SQLite databases. It will return the underlying cursor's id field for the item in position 1.

In your case there isn't an id for the item in position 1: I'm assuming ArrayAdapter's implementation just returns -1 or 0.

EDIT: actually, it just returns the position: in this case 1.

街角迷惘 2024-12-01 08:47:50

如果您正确实现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;

If you implement getItemIdcorrectly then it might be very useful.

Example :

You have a list of albums :

class Album{
     String coverUrl;
     String title;
}

And you implement getItemId like this :

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

Now your item id depends on the values of coverUrl and title fields and if you change then and call notifyDataSetChanged() on your adapter, then the adapter will call getItemId() method of each element and update only thouse items which id has changed.

This is very useful if are doing some "heavy" operations in your getView().

BTW : if you want this to work, you need to make sure your hasStableIds() method returns false;

萝莉病 2024-12-01 08:47:50

我想提一下,在实现 getItemgetItemId 后,您可以使用 ListView.getItemAtPositionListView.getItemIdAtPosition 直接访问您的数据,而不是通过适配器。这在实现 onClick 侦听器时可能特别有用。

I would like to mention that after implementing getItem and getItemId you can use ListView.getItemAtPosition and ListView.getItemIdAtPosition to directly access you data, instead of going through the adapter. This may be particularly useful when implementing an onClick listener.

迷鸟归林 2024-12-01 08:47:50

getItemgetItemId 是少数主要用于将数据附加到列表中的项目的方法。对于 getItem,您可以传递将附加到列表中的项目的任何对象。通常人们会返回nullgetItemId 是您可以附加到列表中相同项目的任何唯一的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);
    }
});

getItem or getItemId are few method mainly designed to attached data with items in the list. In case of getItem, you can pass any object that will attach to the item in the list. Normally people return null. getItemId is any unique long value you can attach with the same item in the list. People generally return the position in the list.

What's the use. Well, as these values are bound to the item in the list, you can extract them when user clicks on the item. These values are accessible through AdapterView methods.

// 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);
    }
});
染火枫林 2024-12-01 08:47:50

如果您的适配器用户界面根据位置发生变化,请使用这两种方法

@Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

in case your adapter ui change according to position use this two methods

@Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文