seleccionar - obtener datos de un listview android
¿Cómo puedo eliminar la dependencia de ListView''s onItemClick/getView y sus tipos de filas? (2)
Otra posibilidad es utilizar los métodos setTag / getTag en la vista de cada elemento en la lista, esto le permite adjuntar el ''Libro'' o ''Categoría'' a su fila apropiada.
Para que esto funcione, cada uno de los elementos ''enumerados'' debe implementar una interfaz común que tenga un método apropiado para ser llamado cuando se haga clic en él.
Por ejemplo:
interface Selectable {
void onSelected(); // Add parameters if necessary...
}
En tu adaptador de lista:
public View getView(int position, View convertView, ViewGroup parent) {
View itemView; // Logic to get the appropriate view for this row.
Selectable theObjectBeingRepresented;
//
// Logic to assign a Book/Category, etc to theObjectBeingRepresented.
// In this example assume there is a magic Book being represented by
// this row.
//
Book aMagicBook = new Book();
theObjectBeingRepresented = aMagicBook;
// If all objects that will be contained in your list implement the
// ''Selectable'' interface then you can simply call setTag(...) with
// the object you are working with (otherwise you may need some conditional logic)
//
itemView.setTag( SELECTABLE_ITEM_KEY, theObjectBeingRepresented );
}
Luego, cuando se hace clic en un elemento:
void onItemClick(AdapterView<?> adapterView, View view, int rowIndex, long rowId)
{
Selectable item = (Selectable)view.getTag( SELECTABLE_ITEM_KEY );
// Depending on how you are populating the list, you may need to check for null
// before operating on the item..
if( null != item ) {
item.onClick(); // Appropriate implementation called...
}
}
Un poco más de detalle sobre el método setTag : documentación setTag
Espero que esto ayude...
Como ejemplo simplificado, considere un ListView
que puede contener tanto subcategorías como títulos de libros. Si se hace clic en un título del libro, debe comenzar una nueva actividad que muestre la imagen de la portada. Si se hace clic en una subcategoría, se muestra una nueva lista de libros y categorías.
Una interfaz de Row
se define de la siguiente manera.
interface Row {
void onClick();
void draw(View v);
}
Me gustaría saber cómo evitar una dependencia del ArrayAdapter
ListView
, así como del implementador de onItemClickListener
en los implementadores de Row
(por ejemplo, Book
y Category
).
Una de las fuerzas que impulsa este requisito es el principio "no se repita" (DRY): la implementación de ArrayAdapter
no necesita cambiar cuando se introducen nuevos tipos de filas.
Perdona mi "UML" rayado de pollo a continuación, pero así es como lo hago.
class ListAdapter extends ArrayAdapter<Row<?>> {
...
public View getView(int position, View convertView, ViewGroup parent) {
View view = listViewRowViewRecycler.getView(convertView);
rowProvider.get().getRow(position).draw(view);
return view;
}
}
El implementador de OnItemClickListener
tiene un método como este:
void onItemClick(AdapterView<?> adapterView, View view, int rowIndex, long rowId)
{
rowProvider.onItemClick(rowIndex);
}
Entonces RowProvider
tiene un método como este:
void onItemClick(int rowIndex) {
rowList.get(rowIndex).onClick();
}
Luego, la interfaz Row
tiene un método con signature void onClick()
y hay implementaciones de Category
y Book
de Row
que proporcionan el comportamiento necesario.