Muy buenas, me llamo Miguel y aquí les traigo este tutorial.
Índice
Una guía para decidir qué clase de animador necesitas
Android nos proporciona una Animator
clase, que consiste en un gran conjunto de clases de funcionalidad que nos permiten realizar cualquier animación en nuestra vista.
Muchos de ellos hacen cosas similares, lo que nos dificulta elegir. Aquí, proporciono una guía simple para seleccionar de acuerdo a sus necesidades.
1. Utilice ViewPropertyAnimator para una animación sencilla
Si planeas animar solo una vista, con animaciones básicas , y no planeas repetirla, usa ViewPropertyAnimator
.
txt_animate.animate().apply { rotationX(3600f) duration = 5000 interpolator = AccelerateDecelerateInterpolator() }.start()
Utilice este enfoque si desea una animación más concisa, ya que no necesita crear una instancia de ningún objeto Animator usted mismo.
Sin embargo, tiene limitaciones:
- La animación no se puede repetir.
- Solo tiene un valor final para animar y ningún valor inicial.
- Solo las animaciones básicas están disponibles para la
animate
función.
Nota: para la animación anterior, si desea que se repita nuevamente manualmente, debe establecer el valor en su origen. es decir, para nuestro caso, establezca lo rotationX = 0f
siguiente, ya que la animación lo ha movido a 3600f
anteriormente.
txt_animate.rotationX = 0f txt_animate.animate().apply { rotationX(3600f) duration = 5000 interpolator = AccelerateDecelerateInterpolator() }.start()
2. Utilice ObjectAnimator para repetir la animación
Si solo desea animar una vista y una animación básica , pero desea que se repita, use ObjectAnimator
.
ObjectAnimator.ofFloat(txt_animate, View.ROTATION_X, 0f, 3600f).apply { duration = 5000 interpolator = AccelerateDecelerateInterpolator() repeatCount = INFINITE repeatMode = REVERSE start() }
Este es el enfoque de animación más utilizado. Forma la base de la animación más básica. A diferencia ViewPropertyAnimator
, tiene un valor de animación inicial, por lo que es repetible.
Como se muestra arriba, todavía está limitado a la animación básica , ya que las View
Propiedades ( por ejemploView.ROTATION_X
) están limitadas a ALPHA, X, Y, Z, TRANSITION_X, TRANSITION_Y, TRANSITION_Z, ROTATION_X, ROTATION_Y, ROTATION, SCALE_X, SCALE_Z
.
Animando cualquier propiedad
Si también necesitamos que se animen otros tipos de propiedades, podríamos usar el enfoque reflexivo, donde solo proporcionamos el nombre de cadena de las propiedades a ObjectAnimator
como se muestra a continuación (es decir textColor
).
ObjectAnimator.ofArgb( txt_animate, "textColor", Color.parseColor("#FFFF0000"), Color.parseColor("#FF0000FF") ).apply { duration = 5000 interpolator = AccelerateDecelerateInterpolator() repeatCount = INFINITE repeatMode = REVERSE start() }
Lo anterior muestra un ejemplo de animación sobre el textColor
uso de las ofArgb
funciones en ObjectAnimator
. Esto lo hace ObjectAnimator
relativamente poderoso y capaz de animar propiedades de cualquier vista.
No obstante, es preferible utilizar la Vista de propiedades dada para la animación utilizando el enfoque de reflexión, ya que tiene un mejor rendimiento.
Animador de objetos basado en XML
También podríamos usar XML para definir nuestro animador de objetos:
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:interpolator/accelerate_decelerate" android:repeatCount="infinite" android:repeatMode="reverse" android:duration="5000" android:propertyName="textColor" android:valueFrom="#FFFF0000" android:valueTo="#FF0000FF" android:valueType="colorType"/>
Luego cargue el XML usando el siguiente código:
(AnimatorInflater.loadAnimator(this,R.animator.custom_animator) as ObjectAnimator).apply { target = txt_animate start() }
Una limitación ObjectAnimator
es que solo puede realizar una única animación en la vista.
3. Utilice PropertyValueHolders para varias animaciones en una vista
Si queremos animar más de una animación en una sola vista, como una combinación de la rotación y el cambio de color del texto de arriba, necesitaremos usar PropertyValueHolder
encima de ObjectAnimator
.
val rotationX = PropertyValuesHolder.ofFloat( View.ROTATION_X, 0f, 3600f) val textColor = PropertyValuesHolder.ofInt( "textColor", Color.parseColor("#FFFF0000"), Color.parseColor("#FF0000FF") ) textColor.setEvaluator(ArgbEvaluator()) ObjectAnimator.ofPropertyValuesHolder(txt_animate, rotationX, textColor).apply { duration = 5000 interpolator = AccelerateDecelerateInterpolator() repeatCount = INFINITE repeatMode = REVERSE start() }
El PropertyValuesHolder
puede aceptar tanto proporcionadas Ver propiedades ALPHA, X, Y, Z, TRANSITION_X, TRANSITION_Y, TRANSITION_Z, ROTATION_X, ROTATION_Y, ROTATION, SCALE_X, SCALE_Z
), así como cualquier objeto vista propiedades a través de la reflexión (por ejemplo textColor
, backgroundColor
).
Titular de vistas de propiedad basadas en XML
También podríamos usar XML para definir nuestro titular de vistas de propiedad.
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:interpolator/accelerate_decelerate" android:repeatCount="infinite" android:repeatMode="reverse" android:duration="5000" > <propertyValuesHolder android:propertyName="rotationX" android:valueFrom="0" android:valueTo="3600" android:valueType="floatType" /> <propertyValuesHolder android:propertyName="textColor" android:valueFrom="#FFFF0000" android:valueTo="#FF0000FF" android:valueType="colorType" /> </objectAnimator>
Luego cargue el XML con lo siguiente en el código:
(AnimatorInflater.loadAnimator(this, R.animator.custom_animator) as ObjectAnimator).apply { target = txt_animate start() }
Este uso solo se limita a la animación que ocurre al mismo tiempo en la misma vista.
4. Use AnimatorSet para múltiples vistas y secuenciación de animaciones
Suponiendo que tiene varias vistas para animar, o tiene una vista pero le gustaría secuenciar las animaciones una tras otra, necesitará usar AnimatorSet
.
val rotationX = PropertyValuesHolder.ofFloat( View.ROTATION_X, 0f, 3600f) val textColorX = PropertyValuesHolder.ofInt( "textColor", Color.parseColor("#FFFF0000"), Color.parseColor("#FF0000FF") ) textColorX.setEvaluator(ArgbEvaluator()) val rotateXColor = ObjectAnimator.ofPropertyValuesHolder( txt_animate, rotationX, textColorX).apply { duration = 5000 interpolator = AccelerateDecelerateInterpolator() } val rotationY = PropertyValuesHolder.ofFloat( View.ROTATION_Y, 0f, 3600f) val textColorY = PropertyValuesHolder.ofInt( "textColor", Color.parseColor("#FF0000FF"), Color.parseColor("#FFFF0000") ) textColorY.setEvaluator(ArgbEvaluator()) val rotateYColor = ObjectAnimator.ofPropertyValuesHolder( txt_animate, rotationY, textColorY).apply { duration = 5000 interpolator = AccelerateDecelerateInterpolator() } AnimatorSet().apply { play(rotateYColor).after(rotateXColor) start() }
Una combinación de ObjectAnimator
, PropertyValuesHolder
y AnimatorSet
, obtienes un conjunto de animación relativamente poderoso.
Una desventaja AnimatorSet
es que no permite la repetición en su conjunto de animación.
Conjunto de animadores basado en XML
También podríamos usar XML para definir nuestro conjunto de animadores:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="5000" android:interpolator= "@android:interpolator/accelerate_decelerate"> <propertyValuesHolder android:propertyName="rotationX" android:valueFrom="0" android:valueTo="3600" android:valueType="floatType" /> <propertyValuesHolder android:propertyName="textColor" android:valueFrom="#FFFF0000" android:valueTo="#FF0000FF" android:valueType="colorType" /> </objectAnimator> <objectAnimator android:duration="5000" android:interpolator="@android:interpolator/accelerate_decelerate"> <propertyValuesHolder android:propertyName="rotationY" android:valueFrom="0" android:valueTo="3600" android:valueType="floatType" /> <propertyValuesHolder android:propertyName="textColor" android:valueFrom="#FF0000FF" android:valueTo="#FFFF0000" android:valueType="colorType" /> </objectAnimator> </set>
Luego cargue el XML con lo siguiente en el código:
(AnimatorInflater.loadAnimator(this, R.animator.custom_animator) as
AnimatorSet).apply {
setTarget(txt_animate)
start()
}
5. Utilice ValueAnimator para la animación personalizable
Suponiendo que desee animar algo que no sea una propiedad de una vista o un objeto, entonces necesitaría usar la clase de animador más básica: ValueAnimator.
Para demostrar esto, planeamos animar el degradado de color del texto:
val paint: TextPaint = txt_animate.paint val width = paint.measureText(txt_animate.text.toString())val textShader: Shader = LinearGradient( 0f, 0f, width, txt_animate.textSize, intArrayOf(Color.GREEN, Color.BLACK, Color.MAGENTA), null, Shader.TileMode.CLAMP )txt_animate.paint.shader = textShader txt_animate.invalidate()
Al observar el código anterior, está claro que no es una propiedad simple del texto. Queremos animar a través del siguiente conjunto de colores:
intArrayOf(Color.RED, Color.RED, Color.RED), intArrayOf(Color.RED, Color.RED, Color.GREEN), intArrayOf(Color.RED, Color.GREEN, Color.BLACK), intArrayOf(Color.GREEN, Color.BLACK, Color.MAGENTA), intArrayOf(Color.BLACK, Color.MAGENTA, Color.BLUE), intArrayOf(Color.MAGENTA, Color.BLUE, Color.BLUE), intArrayOf(Color.BLUE, Color.BLUE, Color.BLUE)
Veamos cómo podemos lograrlo.
Crea un evaluador personalizado
De lo anterior, puede ver que el valor inicial y final de la animación es IntArray
de Color
. Entonces, tendremos que personalizar la transición que queremos.
Android nos proporciona el interface TypeEvaluator<T>
para que implementemos Evaluator
:
class GradientArgbEvaluator : TypeEvaluator<IntArray> { private val argbEvaluator = ArgbEvaluator() override fun evaluate(fraction: Float, startValue: IntArray, endValue: IntArray): IntArray { require(startValue.size == endValue.size) return startValue.mapIndexed { index, item -> argbEvaluator.evaluate( fraction, item, endValue[index]) as Int }.toIntArray() } }
Aprovechamos lo ArgbEvaluator
que ya proporciona Android y hacemos que maneje los IntArray
colores por nosotros, como se indicó anteriormente.
Implemente ValueAnimator con el oyente
Con el GradientArgbEvaluator
, estamos listos para implementar ValueAnimator
:
val paint: TextPaint = txt_animate.paint val width = paint.measureText(txt_animate.text.toString()) ValueAnimator.ofObject( GradientArgbEvaluator(), intArrayOf(Color.RED, Color.RED, Color.RED), intArrayOf(Color.RED, Color.RED, Color.GREEN), intArrayOf(Color.RED, Color.GREEN, Color.BLACK), intArrayOf(Color.GREEN, Color.BLACK, Color.MAGENTA), intArrayOf(Color.BLACK, Color.MAGENTA, Color.BLUE), intArrayOf(Color.MAGENTA, Color.BLUE, Color.BLUE), intArrayOf(Color.BLUE, Color.BLUE, Color.BLUE) ).apply { repeatMode = REVERSE repeatCount = INFINITE duration = 5000 interpolator = AccelerateDecelerateInterpolator() addUpdateListener { val textShader: Shader = LinearGradient( 0f, 0f, width, txt_animate.textSize, it.animatedValue as IntArray, null, Shader.TileMode.CLAMP ) txt_animate.paint.shader = textShader txt_animate.invalidate() } start() }
Como se muestra en el código anterior, ValueAnimator
es casi como ObjectAnimator
, excepto que no tiene una vista específica para apuntar. Tiene que tener un oyente, es decir addUpdateListner
, que escuche el cambio de valor y se comporte en consecuencia. Esto agregó más código, pero mejor personalización.
Tabla de resumen
Aquí hay una tabla para identificar fácilmente qué Animator
función podría usar:
Espero que esto le haya proporcionado alguna orientación útil. Puede obtener el código aquí para acceder a toda la información anterior.
Gracias por leer.
Añadir comentario