2012-07-25 18 views
14

Tengo un ListFragment respaldado por un ArrayAdapter que se rellena con un Loader. Cuando el usuario hace clic en uno de los elementos, quiero pasar una referencia al elemento seleccionado, así como el resto de los elementos de la lista a otro fragmento. Mi pregunta es ¿cómo debería obtener todos los artículos del adaptador? Estas son las posibilidades que veo:Obtener todos los elementos de un ArrayAdapter

1. Mantener una referencia al respaldo List

Crear el adaptador de esta manera:

List<DomainObject> items = new ArrayList<DomainObject>(); 
listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine, items); 

y luego simplemente pasan items o una copia de ella a la siguiente actividad

El inconveniente que veo de esto es que estoy confiando en el hecho no documentado de que la misma lista que paso al constructor contiene los elementos más adelante.

2. Iterar a través del adaptador

Cuando se hace clic en un elemento, iterar a través del adaptador y la acumulación de la lista. Esto parece una cantidad innecesaria de trabajo. Los elementos están contenidos en un List en el adaptador y estoy copiando manualmente cada elemento a una nueva lista.

3. Mantener una lista separada de los elementos cuando se añade al adaptador

Antes de añadir un elemento al adaptador, añadirlo a una lista separada que mantengo en el fragmento. Esto también es un desperdicio ya que la lista de elementos se copia en el ArrayAdapter y el fragmento.

Respuesta

7

La solución que he ido con entretanto es sólo para no utilizar ArrayAdapter. En los casos en los que está luchando contra esta API, parece que es mejor usar el menos completo (y complejo) BaseAdapter. Puede leer más sobre la decisión de ir con BaseAdapter en lugar de ArrayAdapter en este artículo: Android Adapter Good Practices.

+0

Aunque ese artículo es bastante bueno, ignoraría su sección de seguridad de hilos enteros. Está completamente equivocado sobre por qué se supone que hay bloqueos (debido al filtrado que ocurre en un hilo de fondo) y que el 'ArrayAdapter' ya se bloqueará si se invoca' notifyDataSetChanged() 'en cualquier cosa que no sea el hilo de UI. –

+0

@ scompt.com Creo que el enlace que ha publicado está mal explicando ArrayAdapter. Parece explicar solo ArrayAdapter . Estoy un poco confundido ... – theMfromA

+0

En la página que vinculó ... "Solo se puede mostrar texto". => Incorrecto. "Te obliga a proporcionar una lista de elementos de la secuencia de caracteres ..." => Incorrecto "Requiere que proporciones un recurso de diseño que contenga solo una vista de texto" => Incorrecto. Casi todas las suposiciones son incorrectas ... No quiero decir que ArrayAdapter sea mejor que BaseAdapter, pero los conceptos básicos son incorrectos. – Loenix

-2

Creo que el primer método es la mejor manera de hacerlo.

No creo, los datos serían originales para la Otra actividad. porque, pasaría artículos a través del paquete, por lo que el objeto se escribe primero en el paquete y luego en la siguiente actividad que leemos del paquete.

Sin embargo, si está utilizando alguna otra forma para pasar la lista, use list.clone() para crear un nuevo objeto, en lugar de pasar el original.

27

Llego un poco tarde al juego, pero me he encontrado con un problema similar.

Una forma de lidiar con el n. ° 1 sería mantener la referencia a la lista dentro de una subclase de ArrayAdapter, para que su reutilización sea controlada por el objeto adaptador.

Algo así como:

public class DomainAdapter extends ArrayAdapter<DomainObject> { 

    private final List<DomainObject> items; 

    public DomainAdapter(Context context, List<DomainObject> items) { 
     super(context, R.layout.mine, items); 
     this.items = items; 
    } 

    public List<DomainObject> getItems() { 
     return items; 
    } 
} 
+9

Nota. Si planea filtrar el adaptador en algún momento, este método tiene el potencial de fallar. Al realizar un filtro, dentro del ArrayAdapter, se creará una nueva instancia de la Lista. Lo que significa que sus 'elementos' definidos externamente ya no serán la misma lista. Lo que significa que se perderá la sincronización si posteriormente se realizan modificaciones. Puedes leer más sobre esto aquí: http://www.jaysoyer.com/2014/07/constructor-woes-androids-arrayadapter/ –

0

Una prueba rápida dice que el método 1 funciona.Parece ser el más rápido y el más limpio, pero dado que no está documentado, es posible que desee probarlo en las plataformas deseadas y cada vez que se actualice en caso de que la estructura subyacente de ArrayAdapter cambie.

estoy usando compilar la versión SDK 22 y min SDK Versión 10.

0

El mejor método es "mantener una referencia a la lista", pero no pasa "artículos" la variable/parámetro al constructor:

List<DomainObject> items = new ArrayList<DomainObject>(); listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine);

De esta manera, solo crea una instancia de ArrayList como una matriz vacía y tendrá que administrar SU lista usted mismo.

Cuestiones relacionadas