android expandablelistview expand slidedown slideup

android - Efecto deslizante hacia abajo en ExpandableListView



slidedown slideup (5)

¿Es posible tener un buen efecto de deslizamiento hacia arriba / abajo al expandir / contraer un elemento de un ExpandableListView?

Si es así, ¿cómo?

Gracias por adelantado.


Así que este es un duplicado completo de this . En resumen, utilicé una lista regular, realicé mi propia vista desplegable, utilicé una animación desplegable personalizada y cumplí con éxito (mira el enlace para obtener una descripción más detallada).

Edición: Guía paso a paso:

Primero creo el xml list_row:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/row_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/row_simple_parent" > <View android:id="@+id/row_simple_parent_invis_cover" android:visibility="gone" android:layout_height="something that fills out your content" android:layout_width="match_parent" android:background="@android:color/transparent"/> </RelativeLayout> <!-- Dropdown --> <RelativeLayout android:id="@+id/row_dropdown" android:layout_height="wrap_content" android:layout_width="match_parent"> </RelativeLayout> </LinearLayout>

La animación para desplegable es la siguiente:

import android.app.Activity; import android.util.DisplayMetrics; import android.view.View; import android.view.View.MeasureSpec; import android.view.animation.Animation; import android.view.animation.Transformation; /** * Class for handling collapse and expand animations. * @author Esben Gaarsmand * */ public class ExpandCollapseAnimation extends Animation { private View mAnimatedView; private int mEndHeight; private int mStartVisibility; /** * Initializes expand collapse animation. If the passed view is invisible/gone the animation will be a drop down, * if it is visible the animation will be collapse from bottom * @param view The view to animate * @param duration */ public ExpandCollapseAnimation(View view, int duration) { setDuration(duration); mAnimatedView = view; mEndHeight = mAnimatedView.getLayoutParams().height; mStartVisibility = mAnimatedView.getVisibility(); if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) { mAnimatedView.setVisibility(View.VISIBLE); mAnimatedView.getLayoutParams().height = 0; } } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if (interpolatedTime < 1.0f) { if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) { mAnimatedView.getLayoutParams().height = (int) (mEndHeight * interpolatedTime); } else { mAnimatedView.getLayoutParams().height = mEndHeight - (int) (mEndHeight * interpolatedTime); } mAnimatedView.requestLayout(); } else { if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) { mAnimatedView.getLayoutParams().height = mEndHeight; mAnimatedView.requestLayout(); } else { mAnimatedView.getLayoutParams().height = 0; mAnimatedView.setVisibility(View.GONE); mAnimatedView.requestLayout(); mAnimatedView.getLayoutParams().height = mEndHeight; } } } /** * This methode can be used to calculate the height and set itm for views with wrap_content as height. * This should be done before ExpandCollapseAnimation is created. * @param activity * @param view */ public static void setHeightForWrapContent(Activity activity, View view) { DisplayMetrics metrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int widthMeasureSpec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY); view.measure(widthMeasureSpec, heightMeasureSpec); int height = view.getMeasuredHeight(); view.getLayoutParams().height = height; } }

Luego, dentro de mi adaptador (por supuesto, agregará más sintaxis, y si desea que el menú desplegable no se cierre cuando esté fuera de la vista en la lista, también debe recordar esto en el soporte con algún tipo de parámetro):

@Override public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder holder; if(convertView == null) { // setup holder holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.list_row, null); holder.mDropDown = convertView.findViewById(R.id.row_dropdown); convertView.setTag(holder); } else { // get existing row view holder = (ViewHolder) convertView.getTag(); } holder.mDropDown.setVisibility(View.GONE); return convertView; }

Entonces la magia sucede en tus listas en el artículo:

@Override public void onListItemClick(ListView list, View view, int position, long id) { final ListItem item = (ListItem) list.getAdapter().getItem(position); // set dropdown data ViewHolder holder = (ViewHolder) view.getTag(); final View dropDown = holder.mDropDown; // set click close on top part of view, this is so you can click the view // and it can close or whatever, if you start to add buttons etc. you''ll loose // the ability to click the view until you set the dropdown view to gone again. final View simpleView = view.findViewById(R.id.row_simple_parent_invis_cover); simpleView.setVisibility(View.VISIBLE); final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if(msg.what == 0) { // first we measure height, we need to do this because we used wrap_content // if we use a fixed height we could just pass that in px. ExpandCollapseAnimation.setHeightForWrapContent(getActivity(), dropDown); ExpandCollapseAnimation expandAni = new ExpandCollapseAnimation(dropDown, DROP_DOWN_TIME); dropDown.startAnimation(expandAni); Message newMsg = new Message(); } else if(msg.what == 1) { ExpandCollapseAnimation expandAni = new ExpandCollapseAnimation(dropDown, DROP_DOWN_TIME); dropDown.startAnimation(expandAni); simpleView.setOnClickListener(null); simpleView.setVisibility(View.GONE); } } }; simpleView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { handler.sendEmptyMessage(1); } }); // start drop down animation handler.sendEmptyMessage(0); }

Comentario final: No estoy seguro de que esta sea la mejor manera de hacerlo, pero esto es lo que funcionó para mí.

Edición : Hay una solución diferente de DevBytes en youtube que se puede ver here .


Expand / collapse no funciona con el código desde aquí: https://github.com/tjerkw/Android-SlideExpandableListView porque OnItemExpandCollapseListener expandCollapseListener de AbstractSlideExpandableListAdapter es null ; se llama al método notifiyExpandCollapseListener cuando se inicia la animación, pero el oyente es null porque: tiene ActionSlideExpandableListView :

ActionSlideExpandableListView lv = (ActionSlideExpandableListView) findViewById(R.id.list_view); SlideExpandableListAdapter slideAdapter = new SlideExpandableListAdapter(adapter,R.id.expandable_toggle_button, R.id.expandable);

y configura el adaptador: lv.setAdapter(slideAdapter); que llama al método setAdapter desde SlideExpandableListView y allí se crea una nueva instancia de SlideExpandableListAdapter .

Cambié así: el método setAdapter de ActionSlideExpandableListView toma como parámetro AbstractSlideExpandableListAdapter.OnItemExpandCollapseListener que se pasa al método SlideExpandableListView desde SlideExpandableListView . Allí cuando creo SlideExpandableListAdapter también paso este escucha:

public void setAdapter(ListAdapter adapter, AbstractSlideExpandableListAdapter.OnItemExpandCollapseListener expandCollapseListener) { this.adapter = new SlideExpandableListAdapter(adapter, expandCollapseListener); super.setAdapter(this.adapter); } public SlideExpandableListAdapter(ListAdapter wrapped, OnItemExpandCollapseListener expandCollapseListener) { this(wrapped, R.id.expandable_toggle_button, R.id.expandable); setItemExpandCollapseListener(expandCollapseListener); }


La implementación de Warpzit definitivamente funciona, sin embargo, es inutilizable si necesita apoyar a grupos con muchos niños (digamos 100), ya que no utilizará la estructura optimizada de ListView (es decir, la reutilización / reciclaje de vistas infantiles). ). En cambio, terminé extendiendo ExpandableListView para crear un AnimatedExpandableListView que usa la técnica que describí here . Al hacerlo, AnimatedExpandableListView puede animar la expansión del grupo mientras sigue ofreciendo el mejor rendimiento. Echar un vistazo.



Prueba esto en clase java

expListView.setAdapter(listAdapter); expListView.setOnGroupExpandListener(new OnGroupExpandListener() { int previousGroup = -1; @Override public void onGroupExpand(int groupPosition) { if(groupPosition != previousGroup) expListView.collapseGroup(previousGroup); previousGroup = groupPosition; } });