property example android animation

example - spring animation android



Cómo lograr una animación suave de expansión/colapso (4)

Es muy fácil obtener una animación suave (Expandir / Contraer) en la vista

public void expandOrCollapse(final View v,String exp_or_colpse) { TranslateAnimation anim = null; if(exp_or_colpse.equals("expand")) { anim = new TranslateAnimation(0.0f, 0.0f, -v.getHeight(), 0.0f); v.setVisibility(View.VISIBLE); } else{ anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, -v.getHeight()); AnimationListener collapselistener= new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { v.setVisibility(View.GONE); } }; anim.setAnimationListener(collapselistener); } // To Collapse // anim.setDuration(300); anim.setInterpolator(new AccelerateInterpolator(0.5f)); v.startAnimation(anim); }

Y usa este método en tu código. Lo he usado en TextView y está probado. Puede pasar su vista en este método como parámetro.

TextView tv=(TextView)findViewById(R.id.textview); //TO Expand expandOrCollapse(tv,"expand"); //TO Collapse expandOrCollapse(tv,"collapse");

Y disfrutar de un colapso suave y ampliar la animación ................

Me estoy refiriendo al código de expansión / colapso de la animación que se encuentra aquí.

Android: expande / contrae la animación

Aunque funciona, no funciona bien. La animación no es suave.

Hago un poco de registro en el código.

public static void expand(final View v) { v.measure(MeasureSpec.makeMeasureSpec(((View)v.getParent()).getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(1024, MeasureSpec.AT_MOST)); final int targtetHeight = v.getMeasuredHeight(); v.getLayoutParams().height = 0; v.setVisibility(View.VISIBLE); Animation a = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { v.getLayoutParams().height = interpolatedTime == 1 ? LayoutParams.WRAP_CONTENT : (int)(targtetHeight * interpolatedTime); Log.i("CHEOK", "E v.getLayoutParams().height = " + v.getLayoutParams().height); v.requestLayout(); }

Se imprime el siguiente mensaje de registro.

10-09 12:29:58.808: I/CHEOK(7874): E v.getLayoutParams().height = 0 10-09 12:29:58.808: I/CHEOK(7874): E v.getLayoutParams().height = 0 10-09 12:29:58.918: I/CHEOK(7874): E v.getLayoutParams().height = 11 10-09 12:29:59.015: I/CHEOK(7874): E v.getLayoutParams().height = 35 10-09 12:29:59.117: I/CHEOK(7874): E v.getLayoutParams().height = 64 10-09 12:29:59.215: I/CHEOK(7874): E v.getLayoutParams().height = 85 10-09 12:29:59.316: I/CHEOK(7874): E v.getLayoutParams().height = -2 10-09 12:29:59.406: I/CHEOK(7874): E v.getLayoutParams().height = -2

Nueva altura ocurre cada ~ 100 ms. Entonces, el FPS de la animación es alrededor de 10 fps

Quiero ver cuál es la tasa de cuadros de animación ideal. v.requestLayout(); . Obtengo el siguiente registro.

10-09 12:32:06.547: I/CHEOK(8926): E v.getLayoutParams().height = 0 10-09 12:32:06.562: I/CHEOK(8926): E v.getLayoutParams().height = 0 10-09 12:32:06.605: I/CHEOK(8926): E v.getLayoutParams().height = 4 10-09 12:32:06.625: I/CHEOK(8926): E v.getLayoutParams().height = 7 10-09 12:32:06.644: I/CHEOK(8926): E v.getLayoutParams().height = 10 10-09 12:32:06.664: I/CHEOK(8926): E v.getLayoutParams().height = 14 10-09 12:32:06.679: I/CHEOK(8926): E v.getLayoutParams().height = 18 10-09 12:32:06.699: I/CHEOK(8926): E v.getLayoutParams().height = 22 10-09 12:32:06.715: I/CHEOK(8926): E v.getLayoutParams().height = 27 10-09 12:32:06.734: I/CHEOK(8926): E v.getLayoutParams().height = 32 10-09 12:32:06.750: I/CHEOK(8926): E v.getLayoutParams().height = 37 10-09 12:32:06.769: I/CHEOK(8926): E v.getLayoutParams().height = 42 10-09 12:32:06.785: I/CHEOK(8926): E v.getLayoutParams().height = 47 10-09 12:32:06.804: I/CHEOK(8926): E v.getLayoutParams().height = 52 10-09 12:32:06.828: I/CHEOK(8926): E v.getLayoutParams().height = 59 10-09 12:32:06.840: I/CHEOK(8926): E v.getLayoutParams().height = 62 10-09 12:32:06.863: I/CHEOK(8926): E v.getLayoutParams().height = 67 10-09 12:32:06.879: I/CHEOK(8926): E v.getLayoutParams().height = 71 10-09 12:32:06.894: I/CHEOK(8926): E v.getLayoutParams().height = 75 10-09 12:32:06.910: I/CHEOK(8926): E v.getLayoutParams().height = 79 10-09 12:32:06.929: I/CHEOK(8926): E v.getLayoutParams().height = 82 10-09 12:32:06.945: I/CHEOK(8926): E v.getLayoutParams().height = 85 10-09 12:32:06.965: I/CHEOK(8926): E v.getLayoutParams().height = 88 10-09 12:32:06.984: I/CHEOK(8926): E v.getLayoutParams().height = 89 10-09 12:32:07.000: I/CHEOK(8926): E v.getLayoutParams().height = 91 10-09 12:32:07.019: I/CHEOK(8926): E v.getLayoutParams().height = 91 10-09 12:32:07.039: I/CHEOK(8926): E v.getLayoutParams().height = -2 10-09 12:32:07.054: I/CHEOK(8926): E v.getLayoutParams().height = -2

Nueva altura ocurre cada ~ 20ms. Entonces, el FPS de la animación es alrededor de 50 fps

Por supuesto, no puedo eliminar requestLayout , ya que la IU no se actualizará en la pantalla.

Me preguntaba si se puede hacer alguna mejora para lograr un FPS de animación cerrado a 50 fps. Había visto algún producto comercial con un ejemplo sin problemas de Expandir / Contraer. Por lo tanto, creo que esto es algo alcanzable. Solo eso, no estoy seguro exactamente cómo.

Mi código de diseño es el siguiente:

<LinearLayout android:clickable="true" android:id="@+id/chart_linear_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@drawable/dummy" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:orientation="horizontal"> <TextView android:layout_width="0dp" android:width="0dp" android:layout_weight="0.6" android:layout_height="wrap_content" android:gravity="left" android:textSize="20sp" android:textColor="#ff000000" android:text="Summary chart" /> <TextView android:id="@+id/chart_price_text_view" android:layout_width="0dp" android:width="0dp" android:layout_weight="0.4" android:layout_height="wrap_content" android:gravity="right" android:textSize="20sp" android:textColor="#ffF76D3C" android:text="$2.99" /> </LinearLayout> <TextView android:visibility="gone" android:id="@+id/chart_description_text_view" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/currency_exchange_description" android:textColor="#ff626262" android:textSize="15sp" /> </LinearLayout>

Deseo realizar una animación suave en chart_description_text_view desde

Colapsar (Durante el inicio de la aplicación)

Expanding (Cuando el usuario toca en él)

Uno de los "modelos de rol" en los que puedo pensar es https://play.google.com/store/apps/details?id=ch.bitspin.timely . Intente invocar el cuadro de diálogo siguiente desde su elemento de menú Comprar . Te darás cuenta de lo suave que es su animación. No estoy exactamente seguro de cómo logran eso.


Este es un muy buen ejemplo en SlideExpandibleList en Github.

https://github.com/tjerkw/Android-SlideExpandableListView

Espero que esto te ayude a lograr una animación suave y un colapso.

En este ejemplo, guardó el estado del elemento expand list. Así que incluso si se desplaza hacia abajo en la lista, no permitirá que se cierre el elemento de la lista expandida.

En este ejemplo, el evento expand o collapse se proporciona en Button, por lo que debe cambiarlo.

Adjunté las capturas de pantalla.

Espero que esto te ayudará.


La manera más fácil de hacer animaciones es agregar lo siguiente a tu xml para tu diseño lineal:

android:animateLayoutChanges="true"

Funciona muy bien y usa animaciones predeterminadas directamente desde Android


Puedes hacer una animación suave de ver de esta manera:

public class ViewAnimationUtils { public static void expand(final View v) { v.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); final int targtetHeight = v.getMeasuredHeight(); v.getLayoutParams().height = 0; v.setVisibility(View.VISIBLE); Animation a = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { v.getLayoutParams().height = interpolatedTime == 1 ? LayoutParams.WRAP_CONTENT : (int)(targtetHeight * interpolatedTime); v.requestLayout(); } @Override public boolean willChangeBounds() { return true; } }; a.setDuration((int)(targtetHeight / v.getContext().getResources().getDisplayMetrics().density)); v.startAnimation(a); } public static void collapse(final View v) { final int initialHeight = v.getMeasuredHeight(); Animation a = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { if(interpolatedTime == 1){ v.setVisibility(View.GONE); }else{ v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime); v.requestLayout(); } } @Override public boolean willChangeBounds() { return true; } }; a.setDuration((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density)); v.startAnimation(a); } }

Espero que te ayude.