Agregar animación a un ExpandableListView
¿Hay alguna manera de agregar animación al abrir una lista expandible en Android? Lo quiero para que cuando el usuario haga clic en la lista ampliable, tiene una animación / efecto como estoy abriendo un cajón deslizante.
Se mueve lentamente hasta que se abre completamente.
- Después de mantener el estado de colapso / expansión para nivel N o Multinivel lista ampliable algunos subgrupos no se muestran
- Comportamiento del selector de lista expandible de Android
- ¿Cómo mantener abierto el ExpandableListView?
- ¿Cómo implementar el cajón de navegación androide expandible con subitems?
- ¿Cómo mostrar más de 3 niveles de Vista de lista expandible?
- ExpandableListView con múltiples diseños
- Android expandablelistview no se expande ni recibe eventos de clic
- Deslice el efecto hacia abajo en ExpandableListView
- Rellene ExpandableListView con datos de SQLite
- Swipeleft para eliminar no funciona en la altura expandible listview
- Depurando ExpandableListView de la base de datos - no funciona
- ¿Cómo comprobar si el grupo está expandido o colapsado en Android ExpandableListView?
- Android: cacheColorHint = "# 00000000" no funcionan para <ExpandableListView
He pasado mucho tiempo buscando sin suerte. Las soluciones existentes no son lo suficientemente suaves – si su diseño es algo más complejo que sólo 2 botones, se vuelve laggy.
Por lo tanto, he creado mi propio ListAdapter
que almacena en caché la vista completa en un Bitmap
y luego realiza la animación en la vista en caché en lugar de la vista en sí. Funciona mucho más rápido.
Aquí está: https://github.com/dmitry-zaitsev/ExpandableAdapter
La buena noticia es que no es necesario reescribir un montón de código, simplemente envuelva mi ExpandableAdapter
alrededor de su adaptador y proporcione el id de la vista que actuará como un botón de conmutación y el id de la vista que contenga el contenido de la segundo nivel:
new ExpandableAdapter(context, yourAdapter, R.id.switch, R.id.holder);
Y eso es todo.
He tratado de hacer que este trabajo también. He encontrado una solución que funciona para el childViews. Sin embargo, no anima la expansión real del grupo, sino que anima a las células infantiles al llenar el espacio que deja la expansión.
Editar: Hay un error en el colapso, que hará que algunas celdas que no se deben ocultar, se ocultan. Esto probablemente esté relacionado con View-recycling en el listView. Voy a actualizar cuando tengo una solución a esto.
Animación con layoutAnimation en setOnGroupClickListener
mResultList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { if(mResultList.isGroupExpanded(groupPosition)){ mProgAdap.prepareToCollapseGroup(groupPosition); setupLayoutAnimationClose(groupPosition); mResultList.requestLayout(); }else{ boolean autoScrollToExpandedGroup = false; mResultList.expandGroup(groupPosition,autoScrollToExpandedGroup); setupLayoutAnimation(); //*/ } //telling the listView we have handled the group click, and don't want the default actions. return true; } private void setupLayoutAnimation() { AnimationSet set = new AnimationSet(true); Animation animation = new AlphaAnimation(0.0f, 1.0f); animation.setDuration(50); set.addAnimation(animation); animation = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f, 0.5f, 1.0f); animation.setDuration(50); set.addAnimation(animation); LayoutAnimationController controller = new LayoutAnimationController(set, 0.75f); mResultList.setLayoutAnimationListener(null); mResultList.setLayoutAnimation(controller); } private void setupLayoutAnimationClose(final int groupPosition) { AnimationSet set = new AnimationSet(true); Animation animation = new AlphaAnimation(1.0f, 0.0f); animation.setDuration(50); animation.setFillAfter(true); animation.setFillEnabled(true); set.addAnimation(animation); animation = new ScaleAnimation(1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.0f); animation.setDuration(50); animation.setFillAfter(true); animation.setFillEnabled(true); set.addAnimation(animation); set.setFillAfter(true); set.setFillEnabled(true); LayoutAnimationController controller = new LayoutAnimationController(set, 0.75f); controller.setOrder(LayoutAnimationController.ORDER_REVERSE); mResultList.setLayoutAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mResultList.collapseGroup(groupPosition); } @Override public void onAnimationRepeat(Animation animation) { } }); mResultList.setLayoutAnimation(controller); } });
Necesitamos más retoques para hacer que la animación se aplique solamente a los niños reales del grupo expandido / colapsado. Debido a que no podemos sobrecargar la parte correcta en el LayoutAnimationController, necesitamos crear una clase ViewGroup especial. Esta es la misma técnica que en "Can LayoutAnimationController anima sólo las vistas especificadas" .
En ExpandableListViewAdapter, ahora necesitamos un manejo de estado para permitir o ignorar la animación en los elementos de la lista.
@Override public void onGroupExpanded(int groupPos){ super.onGroupExpanded(groupPos); int childCount = getChildrenCount(groupPos); Log.d("EXPLIST","setting children to be expanded:" + childCount); for(int j=0; j < getGroupCount(); j++){ for(int k=0; k < getChildrenCount(j); k++){ GoalServiceCell cell = (GoalServiceCell)getChild(j,k); cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE; } } for(int i=0; i < childCount; i++){ GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i); cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_START_EXPAND; } } public void prepareToCollapseGroup(int groupPos){ int childCount = getChildrenCount(groupPos); for(int j=0; j < getGroupCount(); j++){ for(int k=0; k < getChildrenCount(j); k++){ GoalServiceCell cell = (GoalServiceCell)getChild(j,k); cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE; } } for(int i=0; i < childCount; i++){ GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i); cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_START_COLLAPSIN; } } @Override public void onGroupCollapsed(int groupPos){ super.onGroupCollapsed(groupPos); int childCount = getChildrenCount(groupPos); for(int i=0; i < childCount; i++){ GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i); cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE; } }
Y en el ViewHolder de los niños.
void expandOrCollapse(GoalServiceCell cell,int position){ AnimationAverseRelativeLayout hack = (AnimationAverseRelativeLayout)master; boolean shouldAnim = cell.expandAnimState == GoalServiceCell.ExpandAnimState.SHOULD_START_EXPAND || cell.expandAnimState == GoalServiceCell.ExpandAnimState.SHOULD_START_COLLAPSIN; hack.setIfShouldAnimate(shouldAnim); }
Las GroupViews también están contenidas en AnimationAverseRelativeLayout. Puesto que he fijado "shouldAnimate" al defecto a falso, no necesito tocarlos.
Tuve el mismo problema. Y lo arreglé de una vez por todas. Abro la fuente a github. https://github.com/tjerkw/Android-SlideExpandableListView
Básicamente, incluye esta dependencia del proyecto con su proyecto de Android. Y luego envuelva su ListAdapter
en un SlideExpandableListAdapter
. A continuación, el contenedor agregará la funcionalidad de diapositiva con animación a su ListView
.
Espero que te ayude, ya estoy utilizando en dos proyectos.
Así que lo que he hecho es usar un ListView
regular y luego realizar la animación en onListItemClick. La animación es similar a lo que hago en este enlace: Android animar desplegable / arriba vista adecuada
Pero sólo para una parte de la vista en fila. La vista de filas se implementa de la siguiente manera en xml:
<somelayout> <normal> </normal> <expanded> </expanded> </somelayout>
La normal se usa sin expandir. Cuando se expande está activado, el expandido se establece en visible en vez de desaparecido. Es necesario mantener el control de la configuración de que se volvió a cerrar cuando se cierre (recuerde que esto se establece en sus conversiones que se reciclan).
Puedo aclarar más si es necesario, es sólo un montón de código para poner en.
Eso es lo que hice en estas situaciones.
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder (list1, PropertyValuesHolder.ofInt ("bottom", currentlistHeight, currentlistHeight * 2));
Lo que esto haría es que la altura del listView se duplicará y se animaría. Si establece la altura de la lista actual ZERO . Esto actuaría como un cajón.