¿Cuál es la intención de los métodos getItem y getItemId en la clase Android BaseAdapter?

Tengo curiosidad por el propósito de los métodos getItem y getItemId en el adaptador de clase en el SDK de Android.

De la descripción, parece que getItem debe devolver los datos subyacentes. Por lo tanto, si tengo una serie de nombres ["gato", "perro", "rojo"] y creo un adaptador de usar eso, entonces a.getItem (1) debería devolver "perro", ¿correcto? ¿Qué debería devolver a.getItemId (1) ?

Si usted ha hecho uso de estos métodos en la práctica, podría dar un ejemplo?

Veo estos métodos como un enfoque más limpio para acceder a los datos de mi lista. En lugar de acceder directamente a mi objeto adaptador a través de algo como myListData.get(position) puedo simplemente llamar al adaptador como adapter.get(position) .

Lo mismo ocurre con getItemId . Normalmente usaría este método cuando quisiera ejecutar alguna tarea basada en el ID único de un objeto de la lista. Esto es especialmente útil cuando se trabaja con una base de datos. El id devuelto podría ser una referencia a un objeto en la base de datos que luego podría realizar diferentes operaciones en (update / delete / etc).

Así que en lugar de acceder a la ID desde el objeto de datos sin myListData.get(position).getId() como myListData.get(position).getId() se puede utilizar adapter.getItemId(position) .

Un ejemplo de donde he sentido que necesitaba utilizar estos métodos fue en un proyecto utilizando SeparatedListViewAdapter . Este adaptador puede contener varios tipos diferentes de adaptadores, cada uno representando datos de un tipo diferente (normalmente). Al llamar a getItem(position) en SeparatedListViewAdapter , el objeto devuelto puede ser diferente dependiendo de qué "sección" la posición es la que se envía.

Por ejemplo, si tuviera 2 secciones en su lista (fruta y dulces): Si usó getItem(position) y la position pasó a estar en un elemento en la sección de fruta , recibiría un objeto diferente que si usted solicitó getItem(position) Con la position apunta a un artículo en la sección del caramelo . A continuación, puede devolver algún tipo de valor de ID constante en getItemId(position) que representa el tipo de datos que getItem(position) devuelve, o use instanceof para determinar qué objeto tiene.

Aparte de lo que he mencionado, nunca he sentido como si realmente necesitaba utilizar estos métodos

Bueno, parece que esta pregunta podría ser respondida de una manera más sencilla y sencilla … 🙂

En pocas palabras, Android le permite adjuntar un long a cualquier elemento ListView , es así de simple. Cuando el sistema le avisa de la selección del usuario, recibirá tres variables de identificación para indicarle lo que fue seleccionado:

  • Una referencia a la propia vista,
  • Su posición numérica en la lista,
  • Este long usted se apega a los elementos individuales.

Depende de usted decidir cuál de estos tres es el más fácil para que pueda manejar en su caso particular, pero usted tiene los tres a elegir de todo el tiempo. Piense en esto long que una etiqueta ató automáticamente al artículo, solamente que es incluso más simple y más fácil de leer hacia fuera.

El malentendido acerca de lo que suele ocurrir proviene de una simple convención. Todos los adaptadores tienen que proporcionar un getItemId() incluso si realmente no utilizan esta tercera identificación. Por lo tanto, por convención, esos adaptadores (incluyendo muchos en muestras en el SDK o en toda la web) simplemente devuelven la position por una sola razón: siempre es único. Sin embargo, si un adaptador devuelve la position , esto realmente significa que no quiere utilizar esta función en absoluto, ya que la position ya se conoce, de todos modos.

Por lo tanto, si necesita devolver cualquier otro valor que considere apropiado, no dude en hacerlo:

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

El método getItemId está diseñado principalmente para trabajar con Cursores que están respaldados por bases de datos SQLite. Devolverá el campo de identificación del cursor subyacente para el elemento en la posición 1.

En su caso no hay un id para el elemento en la posición 1: estoy asumiendo que la implementación de ArrayAdapter sólo devuelve -1 o 0.

EDIT: en realidad, sólo devuelve la posición: en este caso 1 .

Me gustaría mencionar que después de implementar getItem y getItemId puede utilizar ListView.getItemAtPosition y ListView.getItemIdAtPosition para acceder directamente a los datos, en lugar de pasar por el adaptador. Esto puede ser particularmente útil cuando se implementa un listener onClick.

Si implementa getItemId correctamente, entonces podría ser muy útil.

Ejemplo:

Tienes una lista de álbumes:

 class Album{ String coverUrl; String title; } 

E implementas getItemId como este:

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

Ahora, su ID de elemento depende de los valores de coverUrl y los campos de título y si cambia y llama a notifyDataSetChanged() en su adaptador, el adaptador llamará al método getItemId () de cada elemento y actualizará sólo los elementos que ha cambiado.

Esto es muy útil si estás haciendo algunas operaciones "pesadas" en tu getView() .

BTW: si desea que esto funcione, debe asegurarse de que su método hasStableIds() devuelve false;

getItem o getItemId son pocos métodos diseñados principalmente para adjuntar datos con elementos de la lista. En caso de getItem , puede pasar cualquier objeto que se adjuntará al elemento de la lista. Normalmente la gente devuelve null . getItemId es cualquier valor long único que se puede adjuntar con el mismo elemento en la lista. La gente generalmente devuelve la posición en la lista.

Cual es el uso. Bueno, ya que estos valores están vinculados al elemento de la lista, puede extraerlos cuando el usuario haga clic en el elemento. Estos valores son accesibles a través de los métodos 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); } }); 
  • ¿Cómo funciona el concepto RecyclerView en android?
  • ¿Cómo actualizar dinámicamente un ListView con un adaptador personalizado?
  • Cómo llamar a notifyDataSetChanged () desde un adaptador genérico
  • Detección de la llamada getView () completada.
  • ¿Es posible obtener referencia a ListView de Adapter en Android?
  • Android: Viewpager y FragmentStatePageAdapter
  • Obtener la posición de la vista de imagen dentro de la vista de lista
  • ¿Quieres implementar notifyDataSetChanged o autorefresh a mi RecyclerView pero no funciona
  • ¿Es Android BaseAdapter un ejemplo de patrón de adaptador?
  • Adaptador de Android múltiple getView
  • Android listviews: vistas de encabezado y pie de página
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.