Android: la posición de la animación se restablece después de completarse

Estoy usando una animación definida xml para deslizar una vista fuera de la pantalla. El problema es que, tan pronto como se completa la animación, se restablece a su posición original. Necesito saber cómo arreglar esto. Aquí está el xml:

  

Aquí está el Java que uso para llamarlo:

  homeScrn = (View)findViewById(R.id.homescreen); slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out); //Set Click Listeners For Menu btnHelp.setOnClickListener(new OnClickListener() { public void onClick(View v) { LayoutInflater.from(getApplicationContext()).inflate(R.layout.help, (ViewGroup)findViewById(R.id.subpage), true); homeScrn.startAnimation(slideLeftOut); } }); 

Entonces, básicamente, lo que sucede es que inflar una vista debajo de uno. Luego animo la vista arriba a la izquierda. Tan pronto como se sale de la pantalla y la animación finaliza, vuelve a su posición original.

Las animaciones funcionan como se esperaba. El hecho de que hayas animado algo no significa que realmente lo hayas movido. Una animación solo afecta los píxeles dibujados durante la animación en sí, no la configuración de los widgets.

Necesita agregar un AnimationListener y, en el método onAnimationEnd() , hacer algo que haga que su movimiento sea permanente (por ejemplo, elimina la vista superior de su elemento primario, marca la vista en la parte superior como si tuviera visibilidad GONE ).

Finalmente obtuve una forma de evitar el problema, la forma correcta de hacerlo es setFillAfter(true) ,

si quieres definir tu animación en xml, entonces deberías hacer algo como esto

    

puedes ver que he definido filterAfter="true" en la etiqueta set , si tratas de definirlo en la etiqueta translate no funcionará, ¡¡podría ser un error en el framework !!

y luego en el Código

 Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out); someView.startAnimation(anim); 

O

 TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0); animation.setFillAfter(true); animation.setDuration(1800); someView.startAnimation(animation); 

¡entonces seguramente funcionará!

Ahora esto es un poco complicado, parece que la vista se mueve a la nueva posición, pero en realidad los píxeles de la vista se mueven, es decir, su vista está en su posición inicial pero no visible, puede probarla si tiene algún botón o haga clic en la vista en su vista (en mi caso en el diseño), para arreglar que tiene que mover manualmente su vista / diseño a la nueva posición

 public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) new TranslateAnimation(-90, 150, 0, 0); 

ahora como podemos ver que nuestra animación comenzará desde -90 x-axis hasta 150 x-axis

entonces, lo que hacemos se establece

 someView.setAnimationListener(this); 

y en

 public void onAnimationEnd(Animation animation) { someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight()); } 

ahora permítanme explicar public void layout (int left, int top, int right, int botton)

mueve tu diseño a la nueva posición primer argumento define la izquierda, que somos 150 , porque la animación de traducir ha animado nuestra vista a 150 x-axis , top es 0 porque no hemos animado el eje y, ahora en la derecha lo hemos hecho someView.getWidth() + 150 básicamente obtenemos el ancho de nuestra vista y agregamos 150 porque nuestra izquierda ahora se mueve a 150 x-axis para hacer que el ancho de la vista sea su origentodos, y bottom es igual al alto de nuestra vista .

Espero que la gente ahora entienda el concepto de traducción, y aún tiene alguna pregunta que pueda formular de inmediato en la sección de comentarios, me complace ayudar 🙂

EDITAR No utilice el método de layout() ya que el marco puede invocarlo cuando se invalide alguna vista y los cambios no se realizarán, utilice LayoutParams para configurar los parámetros de diseño de acuerdo con sus requisitos.

Puede que sea un poco tarde para responder, pero tengo la solución para esto:

Solo agrega android:fillAfter=true en tu xml

Puedes usar

 fillAfter=true fillEnabled=true 

su Vista no se restablecerá a su posición original, pero si tiene algunos botones u otra cosa en su vista, su posición no cambiará.

Debe usar ObjectAnimator , funciona desde el nivel API 11. Cambia la posición de vista automática,

aquí está el ejemplo

 ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX); objectAnimator.setDuration(1000); objectAnimator.start(); 

Gracias JUL por su respuesta

Si su aplicación no encontró el object animator , cambie el nivel de API de Project -> properties -> Android , que import android.animation.ObjectAnimator;

Saludos, Hayk

Necesitas agregar este comando:

 final Animation animSlideLeft = new TranslateAnimation(0, -80, 0,-350, 0, 0, 0, 0); animSlideLeft.setFillAfter(true); 

Pasé a la misma pregunta y la resolví con la configuración de marginLeft en OnAnimationEnd () ..

MarginLayoutParams params = (MarginLayoutParams) this.getLayoutParams(); params.setMargins(this.getWidth()*position, 0,0,0); this.setLayoutParams(params);

Este problema se ha molestado por más de una semana. Y la respuesta de Muhammad me indicó una manera directa de resolverlo.

Usé el diseño de Sever para implementar menús laterales con animación. “view.layout no será persistente. Debería usar LayoutParams, que será persistente”.

Aquí está mi solución: (Use qué tipo de LayoutParameter depende del diseño de su propio padre):

 @Override public void onAnimationEnd(Animation animation) { FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(screenWidth, screenHeight); layoutParams.setMargins((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight); for(View v:views) { v.setLayoutParams(layoutParams); //v.layout((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight); v.clearAnimation(); } } 

Use los métodos de ayuda a continuación para animar fácilmente su vista. Luego puede animar y restablecer después de la finalización de esta manera:

 // Animate the view: fly( view1, (float) 0, (float) 0, (float) 0, (float) 1000, 250, null, null, () -> { // Return the view to initial position on animation end: fly( view1, (float) 0, (float) 0, (float) 0, (float) 0, 0); return null; }); 

Métodos de ayuda:

 /** * Translation of a view. */ public static void fly( View view, float fromXDelta, float toXDelta, float fromYDelta, float toYDelta, int duration) { fly( view, fromXDelta, toXDelta, fromYDelta, toYDelta, duration, null, null, null); } /** * Translation of a view with handlers. * * @param view A view to animate. * @param fromXDelta Amount to shift by X axis for start position. * @param toXDelta Amount to shift by X axis for end position. * @param fromYDelta Amount to shift by Y axis for start position. * @param toYDelta Amount to shift by Y axis for end position. * @param duration Animation duration. * @param start On animation start. Otherwise NULL. * @param repeat On animation repeat. Otherwise NULL. * @param end On animation end. Otherwise NULL. */ public static void fly( View view, float fromXDelta, float toXDelta, float fromYDelta, float toYDelta, int duration, Callable start, Callable repeat, Callable end) { Animation animation; animation = new TranslateAnimation( fromXDelta, toXDelta, fromYDelta, toYDelta); animation.setDuration( duration); animation.setInterpolator( new DecelerateInterpolator()); animation.setFillAfter(true); view.startAnimation( animation); animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { if (start != null) { try { start.call(); } catch (Exception e) { e.printStackTrace(); } } } @Override public void onAnimationEnd(Animation animation) { if (end != null) { try { end.call(); } catch (Exception e) { e.printStackTrace(); } } } @Override public void onAnimationRepeat( Animation animation) { if (repeat != null) { try { repeat.call(); } catch (Exception e) { e.printStackTrace(); } } } }); }