programacion - Android ExpandableListView usando animación
manual de programacion android pdf (4)
La solución @idunnololz funciona muy bien, pero experimenté un comportamiento extraño con mi diseño personalizado para el grupo. La operación de expansión no se ejecutó correctamente, pero el colapso funcionó perfecto. Importé su proyecto de prueba y funcionó bien, así que me di cuenta de que el problema estaba en mi diseño personalizado. Sin embargo, cuando no pude localizar el problema después de una investigación, decidí descomentar estas líneas de código en su AnimatedExpandListView:
if (lastGroup && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return expandGroup(groupPos, true);
}
que causó el problema (mi aplicación está dirigida para Android 4.0+).
Estoy usando
<ExpandableListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ExpandableListView>
Quiero añadir una diapositiva de animación para el niño cuando se hace clic en el elemento principal. Entonces, ¿cómo puedo hacer?
La solución @idunnololz funciona muy bien. Sin embargo, me gustaría agregar un código para colapsar el grupo previamente expandido.
private int previousGroup=-1;
listView.setOnGroupClickListener(new OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
// We call collapseGroupWithAnimation(int) and
// expandGroupWithAnimation(int) to animate group
// expansion/collapse.
if (listView.isGroupExpanded(groupPosition)) {
listView.collapseGroupWithAnimation(groupPosition);
previousGroup=-1;
} else {
listView.expandGroupWithAnimation(groupPosition);
if(previousGroup!=-1){
listView.collapseGroupWithAnimation(previousGroup);
}
previousGroup=groupPosition;
}
return true;
}
});
Actualización final
Ha pasado bastante tiempo desde que escribí esta respuesta. Desde entonces, mucho ha cambiado. El mayor cambio es con la introducción de RecyclerView
que facilita la animación de una lista o una grilla. Recomiendo encarecidamente cambiar a RecyclerView
s si puedes. Para aquellos que no pueden, veré lo que puedo hacer para corregir los errores de mi biblioteca.
Respuesta original
En realidad, no me gusta la implementación popular de una ExpandableListView animada que simplemente utiliza un ListView con una animación de expansión porque en mi caso de uso, cada uno de mis grupos tenía muchos hijos, por lo tanto, no era factible usar un ListView normal como el niño las vistas no se reciclarán y el uso de la memoria será enorme con un rendimiento deficiente. En cambio, opté por un enfoque mucho más difícil pero más escalable y flexible.
Extendí la clase ExpandableListView y anulé las funciones onCollapse y onExpand, también creé una subclase de BaseExpandableListAdapter llamada AnimatedExpandableListAdapter. Dentro del adaptador, anulé la función getChildView e hice que la función fuera definitiva para que la función no se pueda anular de nuevo. En cambio, proporcioné otra función llamada getRealChildView para que las subclases se reemplazaran para proporcionar una vista secundaria real. Luego agregué una bandera de animación a la clase e hice que getChildView devolviera una vista ficticia si la bandera de animación estaba configurada y la vista real si la bandera no estaba configurada. Ahora con el escenario, hago lo siguiente para onExpand:
- Establezca el indicador de animación en el adaptador e indique al adaptador qué grupo se está expandiendo.
- Llamar a
notifyDataSetChanged()
(obliga al adaptador a llamar agetChildView()
para todas las vistas en la pantalla). - El adaptador (en el modo de animación) creará una vista ficticia para el grupo en expansión que tiene una altura inicial 0. El adaptador obtendrá las vistas de niños reales y pasará estas vistas a la vista ficticia.
- La vista ficticia comenzará a dibujar las vistas reales del niño dentro de su propia función
onDraw()
. - El adaptador iniciará un ciclo de animación que expandirá la vista ficticia hasta que tenga el tamaño correcto. También configurará un oyente de animación para que pueda borrar el indicador de animación una vez que la animación se complete y llamará a
notifyDataSetChanged()
también.
Finalmente, con todo esto hecho, pude no solo obtener el efecto de animación deseado sino también el rendimiento deseado, ya que este método funcionará con un grupo de más de 100 niños.
Para la animación colapsada, se necesita hacer un poco más de trabajo para que todo esté configurado y funcionando. En particular, cuando anula la opción Contraer, no desea llamar a la función principal ya que colapsará el grupo de inmediato, dejándolo sin posibilidad de reproducir una animación. En su lugar, desea llamar a super.onCollapse al final de la animación de colapso.
ACTUALIZAR:
Pasé algún tiempo este fin de semana para reescribir mi implementación de este AnimatedExpandableListView y estoy liberando la fuente con un uso de ejemplo aquí: https://github.com/idunnololz/AnimatedExpandableListView/
animateLayoutChanges adds auto-animation
<ExpandableListView
android:animateLayoutChanges="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>