Android: Utilizar ObjectAnimator para traducir una vista con valores fraccionarios de la dimensión de la vista

Parece que las antiguas animaciones de vista ( translate , scale , etc.) ya no son aceptadas por AnimationInflater , al menos como ICS. He leído su código en 4.0.4, y espera explícitamente sólo el set elementos XML, objectAnimator , animator .

Aunque la documentación en http://developer.android.com/guide/topics/resources/animation-resource.html continúa incluyendo las animaciones de vista, parecen estar obsoletas. Intentar utilizarlos resulta en, por ejemplo, el error java.lang.RuntimeException: Unknown animator name: translate .

Como tal, se hace necesario utilizar ObjectAnimator de Android. Sin embargo, no acepta valores fraccionarios de la dimensión asociada de sí mismo o de su padre (ancho para translationX , por ejemplo) como lo hicieron las antiguas animaciones de vista en la forma "75%p" .

Construir ObjectAnimator manualmente en tiempo de ejecución, mediante la búsqueda mediante programación del tamaño del fragmento, no es factible porque FragmentTransaction sólo acepta animaciones declarativas especificadas por un resid.

Mi objetivo es traducir fuera de pantalla un Fragmento que está llenando toda una Actividad (básicamente estoy haciendo una transición de cambio entre dos fragmentos). Esta es la implementación de TranslationAnimation existente ( slide_in_right.xml , que junto con su contraparte slide_out_left.xml es por alguna razón no expuesta en android.R.anim , y por lo tanto tengo que duplicarlos en mi codebase):

 <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="@android:integer/config_mediumAnimTime"/> </set> 

Mi nivel de API está establecido en 14.

¡Gracias!

5 Solutions collect form web for “Android: Utilizar ObjectAnimator para traducir una vista con valores fraccionarios de la dimensión de la vista”

En realidad, los animadores de objetos aceptan valores fraccionarios. Pero quizás usted no entiende el concepto subyacente de un objectAnimator o más generalmente un animador del valor. Un animador de valores animará un valor relacionado con una propiedad (como un color, una posición en la pantalla (X, Y), un parámetro alfa o lo que desee). Para crear tal propiedad (en su caso, xFraction y yFraction) necesita crear sus propios getters y setters asociados a este nombre de propiedad. Digamos que desea traducir un FrameLayout de 0% a 25% del tamaño de toda la pantalla. Entonces usted necesita construir una vista personalizada que envuelve los objetos FrameLayout y escribir sus getters y setters.

 public class SlidingFrameLayout extends FrameLayout { private static final String TAG = SlidingFrameLayout.class.getName(); public SlidingFrameLayout(Context context) { super(context); } public SlidingFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } public float getXFraction() { int width = getWindowManager().getDefaultDisplay().getWidth(); return (width == 0) ? 0 : getX() / (float) width; } public void setXFraction(float xFraction) { int width = getWindowManager().getDefaultDisplay().getWidth(); setX((width > 0) ? (xFraction * width) : 0); } } 

Entonces usted puede utilizar la manera del xml para declarar el animador del objeto que pone xFraction debajo del atributo de la característica xml e inflarlo con un AnimatorInflater

 <?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:propertyName="xFraction" android:valueType="floatType" android:valueFrom="0" android:valueTo="0.25" android:duration="500"/> 

O simplemente puede usar el código de línea java

 ObjectAnimator oa = ObjectAnimator.ofFloat(menuFragmentContainer, "xFraction", 0, 0.25f); 

Espero que te ayude!

Olivier,

La implementación de SDK de Android de FragmentTransaction espera un Animator mientras que, por alguna oscura razón, la implementación de la biblioteca de soporte espera una Animation , si usas la implementación de Fragmento desde la biblioteca de soporte, tu animación de traducción funcionará

Aquí hay un gotcha importante para aquellos que están tratando de crear animaciones de vista como translate y scale .

Las animaciones de propiedades se encuentran en un directorio llamado " animator ": res/animator/filename.xml

PERO, las animaciones de la visión se deben poner en un directorio llamado simplemente " anim ": res/anim/filename.xml

Puse por primera vez mi animación de vista en una carpeta "animador", y estaba confundido acerca de Android Studio quejándose de cómo traducir no era un elemento válido. Por lo tanto, NO , las animaciones de vista no están obsoletas. Sólo tienen su propia ubicación por alguna razón confusa.

Aquí está el ejemplo de trabajo completo (trabajos según lo esbozado por el autor de la respuesta aceptada.)

Presionando el botón se alterna entre 2 fragmentos A y B (por animación de diapositivas de derecha a izquierda). Los fragmentos son sólo texto estúpido (AAAAAA y BBBBB) con diferentes orígenes.

MainActivity.java

 package com.example.slidetrans; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { private static final String TAG = "Main"; boolean showingA = true; Button button; A a; B b; private void incarnate(FragmentManager fm){ int layoutId = R.id.frame; boolean fragmentWasNull = false; Fragment f = fm.findFragmentById(layoutId); if (f == null){ Log.i(TAG, "fragment is null"); if (showingA){ f = a = new A(); } else { f = b = new B(); } fragmentWasNull = true; } else { Log.i(TAG, "fragment is not null"); showingA = (f instanceof A); updateButtonText(); } if (fragmentWasNull){ FragmentTransaction ft = fm.beginTransaction(); ft.add(layoutId, showingA ? a : b, "main").commit(); } } private void updateButtonText(){ button.setText(showingA ? "slide in B" : "slide in A"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); FragmentManager fm = getFragmentManager(); button = (Button)findViewById(R.id.button); incarnate(fm); OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { FragmentManager fm = getFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); transaction.setCustomAnimations(R.anim.in, R.anim.out); transaction.replace(R.id.frame, showingA ? new B() : new A()).commit(); showingA = !showingA; updateButtonText(); } }; button.setOnClickListener(listener); } } 

LL.java

 package com.example.slidetrans; import android.content.Context; import android.util.AttributeSet; import android.widget.LinearLayout; public class LL extends LinearLayout { public LL(Context context) { super(context); } public LL(Context context, AttributeSet attrs) { super(context, attrs); } public float getXFraction() { final int width = getWidth(); if (width != 0) return getX() / getWidth(); else return getX(); } public void setXFraction(float xFraction) { final int width = getWidth(); float newWidth = (width > 0) ? (xFraction * width) : -9999; setX(newWidth); } } 

Main.xml (diseño)

 <?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:orientation="vertical" > <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="slide in B" /> <FrameLayout android:id="@+id/frame" android:layout_width="match_parent" android:layout_height="match_parent" > </FrameLayout> </LinearLayout> 

A.xml (layout)

 <?xml version="1.0" encoding="utf-8"?> <com.example.slidetrans.LL xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#00FF00" > <TextView android:id="@+id/aText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="AAAAAAAAAAAAAAAAAA" android:textSize="30sp" android:textStyle="bold" /> </com.example.slidetrans.LL> 

B.xml (diseño)

 <?xml version="1.0" encoding="utf-8"?> <com.example.slidetrans.LL xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#FFFF00" > <TextView android:id="@+id/bText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" android:textStyle="bold" android:text="BBBBBBBBBB" /> </com.example.slidetrans.LL> 

In.xml (anim)

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="500" android:interpolator="@android:anim/linear_interpolator" android:propertyName="xFraction" android:valueFrom="1.0" android:valueTo="0.0" android:valueType="floatType" /> </set> 

Out.xml (anim)

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="500" android:interpolator="@android:anim/linear_interpolator" android:propertyName="xFraction" android:valueFrom="0.0" android:valueTo="-1.0" android:valueType="floatType" /> </set> 

Las animaciones de vista no están obsoletas. Si utiliza Eclipse, puede encontrarlos en la animación de interpolación como un tipo de recurso al crear un nuevo archivo XML de Android.

  • Fragmento de superposición de animación de transacciones
  • Android se desvanece y se desvanece con ImageView
  • Diseño de material Animación para abrir el formulario
  • RecyclerView: ¿Cómo crear efectos de animación de inserción?
  • Velocímetro Android (indicador de aguja)
  • Condición de carrera al mostrar y ocultar FAB con AnimationUtils
  • Animaciones de widget de pantalla de inicio de Android
  • IOS como sobre el efecto de desplazamiento en Android
  • Manera recomendada de cargar (no interactivo) animaciones (hechas usando Maya) en OpenGL ES en iOS y Android
  • Android: agregar vista con animación de expansión (sin parpadear)
  • CardView muestra artefactos cuando RotationY> 60
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.