transiciones studio programacion móviles libros desarrollo desarrollar curso aprende aplicaciones android android-animation

android - studio - La animación de diseño no funciona en la primera ejecución



programacion android pdf 2018 (6)

Como descubriste, el problema es la visibilidad. Cuando una vista se establece inicialmente como ida en el archivo xml, Android no representará el diseño hasta que la visibilidad cambie a visible o invisible. Si intenta animar en una vista que aún no se ha renderizado, la animación se realizará en la vista sin un diseño. Una vez completada la animación, se procesará y, de repente, la vista aparecerá sin animación. Funciona veces posteriores porque la vista tiene un diseño incluso cuando se establece en ido.

La clave es establecer la visibilidad en invisible en lugar de ir en el archivo xml para que se represente pero esté oculto. Cuando la animación ocurre la primera vez que aparece la vista, se moverá como se espera.

Tengo una Actividad con una lista de elementos y cuando hace clic en un elemento, quiero que los controles de reproducción de ese elemento se deslicen desde la parte inferior de la pantalla y se vuelvan visibles. Definí un conjunto de animación para la diapositiva y la diapositiva y funcionan. Configuré mi animationListener en mi actividad y comencé mi diapositiva en la animación onClick de un elemento. Mi problema es que la primera vez que ejecuto la aplicación, cuando hago clic en un elemento, se ejecuta la devolución de llamada onClick, pero la animación no ocurre. La segunda vez que hago clic, ocurre la diapositiva en la animación, pero no la diapositiva. La tercera y posteriores veces, funciona como se esperaba. Aquí están mis conjuntos de animación.

vm_slide_in.xml

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <translate android:fromYDelta="800" android:toYDelta="0" android:duration="600" /> </set>

vm_slide_out.xml

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <translate android:fromYDelta="0" android:toYDelta="800" android:duration="600" /> </set>

Aquí está el diseño de mi actividad

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/AppBG"> <RelativeLayout style="@style/LogoBar" android:id="@+id/logo_bar" android:layout_alignParentTop="true"> <include layout="@layout/logobar"></include> </RelativeLayout> <RelativeLayout style="@style/TitleBar" android:id="@+id/title_bar" android:layout_below="@+id/logo_bar"> <include layout="@layout/titlebar"></include>" <Button style="@style/TitleBarButton" android:id="@+id/vm_speaker_btn" android:text="@string/vm_speaker_btn_label" android:layout_alignParentLeft="true" android:layout_margin="4dp"> </Button> <Button style="@style/TitleBarButton" android:id="@+id/vm_edit_btn" android:text="@string/vm_edit_btn_label" android:layout_alignParentRight="true" android:layout_margin="4dp"> </Button> </RelativeLayout> <ListView android:id="@+id/@android:id/list" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@+id/title_bar"/> <RelativeLayout android:id="@+id/vm_control_panel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/footer" android:visibility="gone"> <include layout="@layout/vm_control"/> </RelativeLayout> <RelativeLayout android:id="@+id/footer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> <include layout="@layout/taskbar"/> </RelativeLayout> </RelativeLayout>

Aquí está el diseño para el control incluido

<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <RelativeLayout android:id="@+id/vm_control" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/dark_grey"> <TextView android:id="@+id/vm_ctl_branding" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="5dp" android:text="@string/branding" android:textColor="@color/white"> </TextView> <TextView style="@style/TimeMark" android:id="@+id/vm_timestamp" android:layout_toLeftOf="@+id/vm_progress" android:layout_below="@+id/vm_ctl_branding" android:layout_marginRight="3dp" android:text="0:00"> </TextView> <SeekBar android:id="@+id/vm_progress" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_below="@+id/vm_ctl_branding" android:layout_centerHorizontal="true"> </SeekBar> <TextView style="@style/TimeMark" android:id="@+id/vm_timeleft" android:layout_toRightOf="@+id/vm_progress" android:layout_below="@+id/vm_ctl_branding" android:layout_marginLeft="3dp" android:text="-0:00"> </TextView> <LinearLayout android:id="@+id/vm_action_button_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/vm_timestamp" android:layout_alignRight="@+id/vm_timeleft" android:orientation="horizontal" android:layout_below="@+id/vm_progress"> <TextView style="@style/Vm_Action_Button" android:background="@drawable/vm_action_btn_call" android:id="@+id/vm_callback_btn" android:layout_marginRight="5dp" android:text="@string/vm_action_btn_callback"> </TextView> <TextView style="@style/Vm_Action_Button" android:background="@drawable/vm_action_btn_delete" android:id="@+id/vm_delete_btn" android:layout_marginLeft="5dp" android:text="@string/vm_action_btn_delete"> </TextView> </LinearLayout> </RelativeLayout> </merge>

Desde mi método onCreate ...

// Handle list item selections ListView lv = getListView(); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final Voicemail vmItem = (Voicemail) vmla.getItem(position); Toast.makeText(ctx, "Name: " + vmItem.getCallerName() + " Position: " + position, Toast.LENGTH_SHORT) .show(); vVm_controls.startAnimation(mSlideIn); } });

Y mis devoluciones de llamadas de animación ...

@Override public void onAnimationStart(Animation animation) { vm_controls_in = !vm_controls_in; if (vm_controls_in) { vVm_controls.setVisibility(View.GONE); } else { vVm_controls.setVisibility(View.VISIBLE); // vVm_controls.bringToFront(); } } @Override public void onAnimationEnd(Animation animation) { if (!vm_controls_in) { try { Thread.sleep(1000); vVm_controls.startAnimation(mSlideOut); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub }


No sé si todavía está actualizado, pero sí, es un problema con la visibilidad. Así que establecí la visibilidad en el archivo xml en invisible y llamé al lugar donde se inicializó su vista:

view.post(new Runnable() { @Override public void run() { view.animate().translationY(view.getHeight()); } };

Ahora la llamada

view.animate().translationY(0).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); view.setVisibility(View.VISIBLE); } }

funciona también la primera vez


Por supuesto, no 20 minutos después de publicar esta pregunta, descubrí mi problema. Como estaba configurando la visibilidad de mi diseño en "GONE", cuando traté de comenzar la animación, no se activaba por primera vez. No estoy seguro de por qué va la segunda y siguientes veces, pero si configuro la visibilidad como "VISIBLE" justo antes de comenzar la animación, solucionó el problema. Aquí está el código donde lo cambié ...

// Handle list item selections ListView lv = getListView(); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final Voicemail vmItem = (Voicemail) vmla.getItem(position); Toast.makeText(ctx, "Name: " + vmItem.getCallerName() + " Position: " + position, Toast.LENGTH_SHORT) .show(); vVm_controls.setVisibility(View.VISIBLE); vVm_controls.startAnimation(mSlideIn); } });


Tenía exactamente el mismo problema, pero al usar ViewPropertyAnimator . Por ejemplo, declaras un GridView llamado mGridView . Todo lo que tienes que hacer ahora es llamar a mGridView.animate() con los cambios deseados.

La animación de mi GridView se activó pero, debido a circunstancias desconocidas, no había ninguna animación real visible. También cambié todo View.GONE a View.VISIBLE , pero no cambió nada. En mi caso, me di cuenta de que solo tenía que eliminar android:requiresFadingEdge="vertical" en mi XML de este GridView particular. Puede que no sea posible utilizar un Fading Edge en combinación con ViewPropertyAnimator .


Tuve exactamente el mismo problema aunque estaba configurando la vista como visible en el inicio de la animación. Seguí el consejo de Brockoli y lo puse a visible antes de comenzar la animación y funcionó como un amuleto.

ANTES DE:

Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { view.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } ); view.startAnimation(animation);

DESPUÉS:

Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left); view.setVisibility(View.VISIBLE); view.startAnimation(animation);


Tuve un problema similar en Android 4.4.3. Probé la mayor parte de la solución propuesta, pero solo una solución funcionó bien para mí. Tienes que ejecutar tu animación después de que la ventana complete la representación y la mejor manera es ejecutarla dentro de Window FocusChanged . No use la demora mediante Runnable ya que afectará el rendimiento de la aplicación en teléfonos de alta velocidad.

@Override public void onWindowFocusChanged (boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) yourView.startAnimation(anim); }

se puede encontrar más información en esta publicación: https://damianflannery.wordpress.com/2011/06/08/start-animation-in-oncreate-or-onresume-on-android/