Un ListView puede contener fragmentos

Como en, los ELEMENTOS de un ListView pueden ser Fragmentos. Sé que puede asignar un TextView XML a un ListView para cambiar la forma en que se ve, pero puede agregar fragmentos en un ListView.

Por ejemplo: Tengo un Fragmento. El XML de dicho Fragmento contiene un ImageView, un par de TextViews de gran tamaño y un TextView de pequeño estilo. El código de clase Fragment recibe un Bundle, luego basado en el contenido rellena TextViews e ImageView en consecuencia. Tanto el Fragmento XML como el Fragmento funcionan sin problemas (puedo mostrar un Fragmento individual muy bien). Tengo una FragmentActivity en la que quiero mostrar la mencionada lista de Fragmentos. Aquí está el código que estoy usando para intentar poblar el ListView dentro de la vista de FragmentActivity:

ArrayList<Fragment> fragList = new ArrayList<Fragment>(); Fragment fragment = Fragment.instantiate(this, TileItem.class.getName()); Bundle bundle = new Bundle(); bundle.putInt("key", 0); fragment.setArguments(bundle); fragList.add(fragment); ArrayAdapter<Fragment> adapter = new ArrayAdapter<Fragment>(this, R.layout.tile_item, fragList); listItems.setAdapter(adapter); 

Aquí está mi modo de pensar en esto. Hago un ArrayList de fragmentos para mantener todas mis vistas instanciadas. A continuación, crear un fragmento, crear un paquete, agregar datos al Bundle (para que el fragmento puede marshal datos en sus vistas correctamente), agregue el paquete al fragmento y finalmente agregue el fragmento a ArrayList. Después de eso, hago un ArrayAdapter, agrego el diseño del elemento que quiero usar, y la lista de Fragmentos que he hecho; A continuación, establezca ListView para leer de mi adaptador.

Cualquiera que ejecute este código probablemente obtendrá el NPE @ instanciando el ArrayAdapter. ¿Lo que da? ¿Es esto posible? Antes de que continúe atormentando mi cerebro en esto alguien puede decirme si estoy perdiendo mi tiempo? ¿Hay una mejor manera? He estado pensando en usar un ScrollView, pero tanto de la funcionalidad de un ListView necesitaría volver a implementar y odio-odio-odio reinventar la rueda cuando no es necesario.

Gracias a cualquiera que lea, y especialmente gracias por sus pensamientos si decide dejarlos. He intentado buscar alrededor para una respuesta establecida a esto pero todo lo que parece encontrar son preguntas / páginas web sobre el uso de un ListView INSIDE de un fragmento; No utilizar Fragmentos COMO LOS ELEMENTOS de un ListView

Edit: Tomé las sugerencias a continuación y comencé a investigar más. De la forma en que aparecen las cosas debería ser capaz de utilizar un adaptador personalizado que infla fragmentos en lugar de simplemente plana a partir de construcción de XML (a falta de una mejor manera de describir el proceso) Sin embargo, mi aplicación actual es lanzar un NPE al intentar establecer El adaptador.

Aquí está mi código de adaptador personalizado (abreviado por brevedad):

 public class AdapterItem extends ArrayAdapter<Fragment> { Context c; List<Fragment> f; public AdapterItem(Context c, List<Fragment> f) { super(c, R.layout.tile_item, f); this.c = c; this.f = f; } @Override public View getView(int pos, View v, ViewGroup vg) { LayoutInflater i = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); return i.inflate(R.layout.tile_item, vg, false); } 

}

Y aquí es cómo lo estoy implementando:

 ArrayList<Fragment> fragList = new ArrayList<Fragment>(); Fragment fragment = Fragment.instantiate(this, TileItem.class.getName()); Bundle bundle = new Bundle(); bundle.putInt("key", 0); fragment.setArguments(bundle); fragList.add(fragment); AdapterItem adapter = new AdapterItem(this, fragList); adapter.add(fragment); listItems.setAdapter(adapter); 

Así que ha sido unos días y estoy bastante seguro de que este hilo ha sido enterrado. Sin embargo, pensé que me gustaría añadir una última actualización sólo en caso de que alguien quiere probar esto y una búsqueda en google trae aquí. Así que en mi implementación estoy recibiendo un NPE cuando el ListView se da el adaptador. No se necesita un cirujano de cohetes para averiguar que es sin duda el adaptador y no el ListView lanzar el error. Por la vida de mí no puedo entender por qué …

En cualquier caso, creo que tengo una idea. En primer lugar, una historia poco atrás: Hace un tiempo estaba tratando de hacer FragmentTransactions dentro de un FragmentDialog. Cada vez que intentaba hacerlo, tendría un NPE. Eventualmente, con mucha investigación, descubrí que la razón pertenecía a la manera que los fragmentos son instanced. Cuando un Fragmento es llamado, necesita el contexto de su padre. Dado que el padre de un diálogo es la actividad que lo inició, el propio diálogo no cumplió los criterios necesarios. Creo, que al intentar agregar fragmentos a un ListView, este es también el caso. Puesto que el ListView no cumple el acuerdo con instanciar un Fragmento lanza el NPE y así, me deja colgando y volviendo a convenciones. D @ mn … Realmente había esperado que sería capaz de hacer esto. El uso de fragmentos en lugar de simple XML habría hecho mucho más fácil organizar / buscar a través de la lista. Oh bien … supongo que no se puede hacer en caso de que alguien se esté preguntando.

Yo diría que esto no es posible hacer como poner un fragmento en un ListView significaría que el fragmento se puede multiplicar a través de múltiples contenedores. Cuando se utiliza el FragmentManager para crear un fragmento, se marca con un identificador, por lo que es sencillo volver a cargar y reordenar en la orientación y otros cambios de configuración. También fomenta los usos a través de múltiples configs de dispositivo.

Un Fragmento es realmente un subconjunto de una Actividad. ¿Alguna vez tendría una actividad como parte de una lista? Definitivamente no (debería ser la respuesta!) !!!

Por otra parte, no es muy útil adjuntar () y separar () un fragmento continuamente a medida que se mueven dentro y fuera de la vista (las células se reciclan). Estas son todas las operaciones costosas que un ListView no debe tratar. Las listas deben desplazarse rápidamente.

De la conversación sobre los comentarios, puedo ver que desea lograr código agradable con una buena separación de código de configuración de vista y el adaptador en la actividad. Hágalo con:

  1. Substituya la clase de la View y haga su dibujo y disposición de encargo allí.
  2. Cree una nueva clase, en la que suministre un contexto y un conjunto de datos necesarios para que le devuelva la vista que debe mostrar una lista, esto es lo que suelo hacer.
  3. Tener una clase Utils para construir su video en otro lugar (tonto).

Simplemente no utilice Fragmentos en las listas. No es el caso de uso que están apuntando. HTH.

Resulta que puede crear un ListView donde cada elemento en el listView es un Fragment . El truco es envolver el Fragmento en un FrameLayout .

ACTUALIZACIÓN 16/09/2014

Aunque es posible crear un ListView que contenga Fragments , no parece que sea una buena idea. Esto parece ser definitivamente un caso de esquina en el mundo de Android y hay dragones. Para un fragmento simple como el del ejemplo a continuación, todo funciona maravillosamente, pero si tienes un proyecto complejo con mucho que hacer en él, entonces este no es probablemente el camino a seguir. Mi nuevo enfoque es extraer todo el código relacionado con la interfaz gráfica de usuario en una View que expande FrameLayout e insertarla en un ListView . Esto funciona MUCHO MEJOR y está más en línea con lo que Android espera que se utilice. Si necesita la funcionalidad de un Fragment en otras partes de su código, simplemente puede usar esta nueva View allí también.

Volver a la respuesta original …

He añadido un nuevo ejemplo de ManyFragments a mi aplicación de ejemplo de AnDevCon 14 Fragmentos si quieres probarlo. Esencialmente viene abajo del BaseAdapter , que en mi ejemplo se parece a esto:

  BaseAdapter adapter = new BaseAdapter() { @Override public int getCount() { return 10000; } @Override public Object getItem(int i) { return new Integer(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { if (view!=null){ ManyListItemFragment fragment = (ManyListItemFragment) view.getTag(); fragment.setCount(i); } else { FrameLayout layout = new FrameLayout(getActivity()); layout.setLayoutParams(frameLayoutParams); int id = generateViewId(); layout.setId(id); ManyListItemFragment fragment = new ManyListItemFragment(); fragment.setCount(i); getChildFragmentManager() .beginTransaction() .replace(id,fragment) .commit(); view = layout; view.setTag(fragment); } return view; } }; 

En caso de que usted es curioso aquí es generateViewId ():

 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static int generateViewId() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { for (;;) { final int result = sNextGeneratedId.get(); // aapt-generated IDs have the high byte nonzero; clamp to the range under that. int newValue = result + 1; if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0. if (sNextGeneratedId.compareAndSet(result, newValue)) { return result; } } } else { return View.generateViewId(); } } private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1); 

No es necesario utilizar Fragmentos.

Escriba un ViewAdapter personalizado y hágale inflar un diseño más complejo (o quizás varios diseños más complejos si usted necesita conseguir realmente extravagante) entonces puebla los campos del diseño según lo necesario.

[Además: a las personas que respondieron en los comentarios – por favor, utilice las respuestas en lugar de comentarios si realmente está respondiendo a la pregunta! ¡Si sólo es porque tienes más puntos de reputación de esa manera!]

  • Desplazar un ListView por píxeles en Android
  • ¿Por qué Google utiliza Canvas en la vista de la lista de conversaciones de aplicaciones de Gmail?
  • ¿Cómo puedo obtener uri del elemento ListView que se rellena con Cursor Adapter
  • Android ignora el tamaño de la barra de desplazamiento
  • ¿Cómo actualizar el contenido de ViewPager?
  • Un montón de recolección de basura en un listview
  • Establecer oyente de clic largo para listview
  • Cómo ocultar el popup de filtro en ListView en Android?
  • Cómo cambiar el color de texto de un elemento ListView?
  • Cómo actualizar la lista expandible cuando se agrega un elemento nuevo
  • SQLiteDatabase actualización no funciona?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.