web-dev-qa-db-fra.com

Quelle est l'intention des méthodes getItem et getItemId dans le Android class BaseAdapter?)?

Je suis curieux de savoir quel est le but des méthodes getItem et getItemId dans l'adaptateur de classe du Android SDK.

D'après la description, il semble que getItem devrait renvoyer les données sous-jacentes. Donc, si j’ai un tableau de noms ["cat","dog","red"] Et que je crée un adaptateur a, alors a.getItem(1) devrait renvoyer "chien", correct? Que doit a.getItemId(1) renvoyer?

Si vous avez utilisé ces méthodes dans la pratique, pourriez-vous donner un exemple?

150
oneporter

Je considère ces méthodes comme une approche plus simple pour accéder aux données de ma liste. Au lieu d'accéder directement à mon objet adaptateur via quelque chose comme myListData.get(position), je peux simplement appeler l'adaptateur comme adapter.get(position).

Il en va de même pour getItemId. En général, j'utilisais cette méthode lorsque je souhaitais exécuter une tâche en fonction de l'ID unique d'un objet de la liste. Ceci est particulièrement utile lorsque vous travaillez avec une base de données. Le id renvoyé pourrait être une référence à un objet de la base de données sur lequel je pourrais ensuite effectuer différentes opérations (mettre à jour/supprimer/etc.).

Ainsi, au lieu d'accéder à l'ID de l'objet de données brutes comme myListData.get(position).getId(), vous pouvez utiliser adapter.getItemId(position).

Un exemple d'utilisation de ces méthodes dans un projet utilisant le SeparatedListViewAdapter . Cet adaptateur peut contenir plusieurs types différents d'adaptateurs, chacun représentant des données d'un type différent (généralement). Lors de l'appel de getItem(position) sur le SeparatedListViewAdapter, l'objet renvoyé peut être différent selon la "section" à laquelle vous l'envoyez.

Par exemple, si vous aviez 2 sections dans votre liste (fruits et bonbons): Si vous utilisiez getItem(position) et position, il se trouvait qu’un élément se trouvait dans le fruit , vous recevrez un objet différent de celui que vous demanderiez getItem(position) avec position pointant vers un élément de la bonbons section. Vous pouvez ensuite renvoyer une sorte de valeur d'identifiant constant dans getItemId(position), qui représente le type de données renvoyé par getItem(position), ou bien utiliser instanceof pour déterminer quel objet vous avez.

À part ce que j'ai mentionné, je n'ai jamais ressenti le besoin d'utiliser ces méthodes

86
binnyb

Eh bien, il semble que cette question pourrait recevoir une réponse plus simple et plus simple ... :-)

Autrement dit, Android vous permet d’attacher un long à n’importe quel élément ListView, c’est aussi simple. Lorsque le système vous informe de la sélection de l’utilisateur, vous recevez trois identifiant les variables pour vous dire ce qui a été sélectionné:

  • une référence à la vue elle-même,
  • sa position numérique dans la liste,
  • ceci long vous avez attaché aux éléments individuels.

C'est à vous de décider lequel de ces trois problèmes est le plus facile à gérer dans votre cas particulier, mais vous avez le choix parmi tous les trois. Pensez à ceci long comme une balise automatiquement attachée à l'élément, mais elle est encore plus simple et plus lisible.

Le malentendu sur ce qu'il fait habituellement provient d'une simple convention. Tous les adaptateurs doivent fournir une getItemId() même s'ils n'utilisent pas cette troisième identification. Ainsi, par convention, ces adaptateurs (y compris de nombreux exemples dans le SDK ou sur le Web) renvoient simplement position pour une seule et même raison: ils sont toujours uniques. Néanmoins, si un adaptateur retourne position, cela signifie vraiment qu'il ne veut pas utiliser cette fonctionnalité du tout, car position est déjà connu, de toute façon.

Donc, si vous devez restituer toute autre valeur que vous jugez utile, n'hésitez pas à le faire:

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

La méthode getItemId est largement conçue pour fonctionner avec des curseurs sauvegardés par des bases de données SQLite. Cela retournera le champ id du curseur sous-jacent pour l'élément en position 1.

Dans votre cas, il n'y a pas d'identifiant pour l'élément en position 1: je suppose que l'implémentation de ArrayAdapter renvoie simplement -1 ou 0.

EDIT: en fait, il retourne simplement la position: dans ce cas 1.

6
Femi

Je voudrais mentionner qu'après avoir implémenté getItem et getItemId, vous pouvez utiliser ListView.getItemAtPosition et ListView.getItemIdAtPosition pour accéder directement à vos données , au lieu de passer par l’adaptateur. Cela peut être particulièrement utile lorsque vous implémentez un écouteur onClick.

4
leo9r

Si vous implémentez getItemIdcorrectement, cela pourrait être très utile.

Exemple :

Vous avez une liste d'albums:

class Album{
     String coverUrl;
     String title;
}

Et vous implémentez getItemId comme ceci:

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

Votre identifiant d'élément dépend maintenant des valeurs des champs coverUrl et title et si vous modifiez alors et appelez notifyDataSetChanged() sur votre adaptateur, celui-ci appellera La méthode getItemId () de chaque élément et ne met à jour que les éléments dont l'identifiant a changé.

Ceci est très utile si vous effectuez des opérations "lourdes" dans votre getView().

BTW: si vous voulez que cela fonctionne, vous devez vous assurer que votre méthode hasStableIds() renvoie false;

4
Danylo Volokh

getItem ou getItemId sont quelques méthodes principalement conçues pour attacher des données avec des éléments de la liste. Dans le cas de getItem, vous pouvez transmettre tout objet à attacher à l’élément de la liste. Normalement, les gens retournent null. getItemId est une valeur unique long que vous pouvez attacher avec le même élément de la liste. Les gens retournent généralement la position dans la liste.

Quel en est l'usage. Comme ces valeurs sont liées à l’élément de la liste, vous pouvez les extraire lorsque l’utilisateur clique dessus. Ces valeurs sont accessibles via les méthodes 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);
    }
});
1
Uday Hiwarale