Ver animación y animación de fotogramas de la animación de Android

La animación de Android se puede dividir en tres categorías:

1> Ver animación también se conoce como: interpolación 

2> Animación de cuadros

3> Animación de propiedad

 

================== [ Ver animación ] =========================

Hay 5 tipos:

Transparencia de gradiente alfa                            
escala de efecto de animación escala de                             tamaño de gradiente efecto de animación de escala
traducir                        la posición de transición de la pantalla mover efecto de animación
rotar                            transferencia de pantalla rotación
diseño de efecto de animación de rotación Aplicación de            control de contenedor de animación animación unificada

 

 

Primero, los pasos específicos para crear un directorio son los siguientes:

 

Elija: directorio anim

 

OK, mira el directorio, crea un archivo de animación: set

 

Nombre: my_animat

 

Bien, agreguemos la animación que necesitamos a este conjunto.

Puede ser una animación o una combinación de varias animaciones.    

Ahora veamos uno por uno para demostrar la pintura en movimiento horizontal:

【traducir】

Mire la configuración de la vista de destino de la animación, se usa una vista de texto.  Nota: el ancho y la altura usados ​​son 300 px píxeles ,,, píxeles ,,, píxeles

Por que usar px, hablaré de eso  

<TextView
            android:id="@+id/tv_animator"
            android:layout_width="300px"
            android:layout_height="300px"
            android:background="@color/color_00a3f3"
            android:text="animator"
            android:textColor="@color/color_7e4513"
            android:gravity="center"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
    />

 

Luego, la animación translate_ani.xml       nota: fillAfter = "true"  View permanecerá al final de la animación al final

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:fillAfter="true">

    <!-- 平移  对应 TranslateAnimation
    fromXDelta,fromYDelta   起始时X,Y座标,如果是0,0,就从远处开启
    toXDelta, toYDelta     动画结束时X,Y的座标 这个坐标是相对于 原始位置(0,0)的
    看下 toXDelta  toYDelta  和TextView 宽高同是 300
    -->
    <translate
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="300"
            android:toYDelta="300"
            android:duration="500">
    </translate>

</set>

 

Eche un vistazo a la captura de pantalla original.

 

Mira el diseño en Actividad: activity_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".animator.AnimatorActivity">


    <TextView
            android:id="@+id/tv_animator"
            android:layout_width="300px"
            android:layout_height="300px"
            android:background="@color/color_00a3f3"
            android:text="目标动画"
            android:textColor="@color/color_7e4513"
            android:gravity="center"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
    />


    <TextView
            android:id="@+id/tv_animator1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="@dimen/dp10"
            android:layout_marginTop="@dimen/dp100"
            android:text="平移动画"
            android:background="@color/color_999999"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_animator"/>

    <TextView
            android:id="@+id/tv_animator2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="@dimen/dp10"
            android:layout_marginTop="@dimen/dp10"
            android:text="透明动画"
            android:background="@color/color_999999"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_animator1"/>

    <TextView
            android:id="@+id/tv_animator3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="@dimen/dp10"
            android:layout_marginTop="@dimen/dp10"
            android:text="旋转动画"
            android:background="@color/color_999999"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_animator2"/>

    <TextView
            android:id="@+id/tv_animator4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="@dimen/dp10"
            android:layout_marginTop="@dimen/dp10"
            android:text="缩放动画"
            android:background="@color/color_999999"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_animator3"/>
</android.support.constraint.ConstraintLayout>

 

 

 

Código de actividad:

package com.leo.dicaprio.myutilapp.animator

import android.content.Context
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.animation.AnimationUtils
import android.widget.Toast
import com.leo.dicaprio.myutilapp.R
import kotlinx.android.synthetic.main.activity_animator.*
import org.jetbrains.anko.startActivity

class AnimatorActivity : AppCompatActivity() {

    companion object {
        fun launch(context: Context) {
            context.startActivity<AnimatorActivity>()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_animator)
        tv_animator.setOnClickListener { Toast.makeText(this, "被单击了", Toast.LENGTH_LONG).show() }
        tv_animator1.setOnClickListener { startAni1() }
        tv_animator2.setOnClickListener { startAni2() }
        tv_animator3.setOnClickListener { startAni3() }
        tv_animator4.setOnClickListener { startAni4() }
    }


    /**
     *      平移动画
     * */
    private fun startAni1() {
        //先加载 平移动画
        val animation = AnimationUtils.loadAnimation(this, R.anim.translate_ani)
        tv_animator.startAnimation(animation)
    }

    

}

 

Haga clic una vez, el efecto de animación no producirá gif, cargue directamente el resultado final

 

Puedes ver el resultado final. En este momento, el teléfono móvil abrió el diseño de borde del modo de desarrollador.

Análisis:

El ancho y la altura de la vista del objetivo son 300 * 300 píxeles, y ahora toXDelta y toYDelta de la animación son 300, lo que significa mover 300 píxeles en la dirección positiva del eje XY.

¿Por qué es tan seguro que la unidad de toXDelta es el píxel? De la captura de pantalla, se puede entender que la Vista de destino se basa en la distancia movida por el punto de origen (coordenadas de la esquina superior izquierda) en la dirección XY, que es exactamente el ancho y la altura del destino. . .

Por cierto! En este momento, si hace clic en el área azul, Taost no se reproducirá. Toast sólo se reproducirá cuando haga clic en la posición original. Entonces la animación de la vista no ha cambiado

Ver propiedades. Por lo tanto, si la vista de animación de destino tiene un evento de clic, la función no se puede lograr con la vista de animación. . . Presta atención a esto.

 

Muy bien, básicamente comprensible. De hecho, la etiqueta translate corresponde a TranslateAnimation () 

Puedes usarlo, el código se cambia a:

    /**
     *      平移动画
     * */
    private fun startAni1() {
        //先加载 平移动画
//        val animation = AnimationUtils.loadAnimation(this, R.anim.translate_ani)
//        tv_animator.startAnimation(animation)

        //单位是像素
        val translateAnimation = TranslateAnimation(0F, 300F,0F , 300F)
        translateAnimation.fillAfter = true//停留在结束地方
        translateAnimation.duration = 500//时间
        tv_animator.startAnimation(translateAnimation)
    }

¡El mismo efecto! ! !

Además, a través de este TranslateAnimation, también puede monitorear el estado de ejecución de la animación, como: inicio, fin, repetición ...

como:

    /**
     *      平移动画
     * */
    private fun startAni1() {
        //先加载 平移动画
//        val animation = AnimationUtils.loadAnimation(this, R.anim.translate_ani)
//        tv_animator.startAnimation(animation)

        val translateAnimation = TranslateAnimation(0F, 300F, 0F, 300F)
        translateAnimation.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationRepeat(animation: Animation?) {
                //动画重复
            }

            override fun onAnimationEnd(animation: Animation?) {
                //动画结束
            }

            override fun onAnimationStart(animation: Animation?) {
                //动画开始
            }

        })
        translateAnimation.fillAfter = false//停留在结束地方
        translateAnimation.duration = 500//时间
        tv_animator.startAnimation(translateAnimation)
    }

 

【alfa】

La transparencia es relativamente simple. . . . En el código alpha_ani.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:fillAfter="true">

    <!--透明
        fromAlpha:开始时透明度 0.0- 1.0   0.0全透明  1.0不透明
        toAlpha: 结束时透明度 0.0- 1.0
        duration:动画持续时间 单位 毫秒
        fillAfter:动画结束后是否停留在结束位置,true停留
        -->
    <alpha android:fromAlpha="1"
           android:toAlpha="0"
           android:duration="10000"
    >
    </alpha>

</set>

 

Referencia de actividad

    /**
     *      透明动画
     * */
    private fun startAni2() {
        //先加载 透明动画
        val animation = AnimationUtils.loadAnimation(this, R.anim.alpha_ani)
        tv_animator.startAnimation(animation)

        /*
        *       或者
        * */
        val alphaAnimation = AlphaAnimation(1.0F, 0F)
        alphaAnimation.fillAfter = true
        alphaAnimation.duration = 5000
        tv_animator.startAnimation(alphaAnimation)
    }

 

【Girar】

Rotación, generalmente cuatro parámetros

fromDegrees    开始时的角度
toDegrees      结束时角度 ,正代表顺时针
pivotX         旋转中心轴点 X坐标 不指定 默认是View 左上角 X坐标   单位像素
pivotY         旋转中心轴点 Y坐标 不指定 默认是View 左上角 Y坐标   单位像素

 

No digas tonterías, ve a la vista de destino, jaja, también es una vista de texto, que también tiene 300 * 300 px

    <TextView
            android:id="@+id/tv_animator"
            android:layout_width="300px"
            android:layout_height="300px"
            android:background="@color/color_00a3f3"
            android:text="目标动画"
            android:textColor="@color/color_7e4513"
            android:gravity="center"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
    />

 

 

Subir archivo de animación: anim /rotate_ani.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:fillAfter="true">

    <!--
        fromDegrees  	开始时的角度
        toDegrees    	结束时角度 ,正代表顺时针
        pivotX  	    旋转中心轴点 X坐标 不指定 默认是View 左上角 X坐标
        pivotY 	        旋转中心轴点 Y坐标 不指定 默认是View 左上角 Y坐标
        -->
    <rotate android:fromDegrees="0"
            android:toDegrees="180"
            android:pivotY="150"
            android:pivotX="150"
            android:duration="5000">
    </rotate>

</set>

 

¡Nota! ! ! pivotX y pivotY son 150, que es exactamente la mitad del ancho y alto de TextView.

Llamada de actividad:

    /**
     *      旋转动画
     * */
    private fun startAni3() {
        //先加载 旋转动画
        val animation = AnimationUtils.loadAnimation(this, R.anim.rotate_ani)
        tv_animator.startAnimation(animation)

        /*
        *       或者
        * */
        val rotateAnimation = RotateAnimation(0F, 180F, 150F, 150F)
        rotateAnimation.fillAfter = true
        rotateAnimation.duration = 5000
        tv_animator.startAnimation(rotateAnimation)
    }

El resultado de la prueba es que cuando TextView es de 300 * 300 px,

1> Tanto pivotX como pivotY son 150, y el centro de rotación es el centro de TextView

1> pivotX y pivotY son ambos 0, y el centro de rotación es la esquina superior izquierda de TextView

Por lo tanto, la conclusión es: las coordenadas del punto giratorio se basan en las coordenadas de la esquina superior izquierda (0,0) de la Vista de destino.

 

 

【Escala】

Enfocar. . . . . .

fromXScale,fromYScale   X Y 方向  缩放起始值
toXScale, toYScale     X Y 方向  缩放结束值
pivotX ,pivotY          X Y 方向  缩放中心值   中心点也是和上面的基准规则一样

Los códigos no se publican, todos son el mismo principio. . . . .

 

============ [Se reproducen varias animaciones juntas o en secuencia] =============

Reproduce varias animaciones simultáneamente :

my_toget__animat.xml代码:   多个动画(透明,旋转,缩放)一起
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <alpha android:fromAlpha="1"
           android:toAlpha="0"
           android:duration="5000">
    </alpha>

    <rotate android:fromDegrees="0"
            android:toDegrees="180"
            android:pivotY="150"
            android:pivotX="150"
            android:duration="5000">
    </rotate>

    <scale android:fromXScale="0"
           android:fromYScale="0"
           android:toXScale="1"
           android:toYScale="1"
           android:pivotX="150"
           android:pivotY="150"
           android:duration="5000">
    </scale>

</set>

 

Procesamiento de la capa de vista: el resultado de la operación es (transparencia, rotación, zoom) por parte de los compañeros

private fun animationSet(){
        //加载 
        val animation = AnimationUtils.loadAnimation(this, R.anim.my_toget__animat)
        tv_animator_view.startAnimation(animation)
    }

 

Esto se puede hacer sin el tipo xml y puede usar código dinámico, como:

private fun animationSet(){
        val rotateAnimation = RotateAnimation(0F, 180F, 150F, 150F)
        val alphaAnimation = AlphaAnimation(1.0F, 0F)
        val scaleAnimation = ScaleAnimation(0F, 1F, 0F, 1F, 150F, 150F)

        //多个动画 放进 AnimationSet 
        val animationSet = AnimationSet(true)
        animationSet.addAnimation(rotateAnimation)
        animationSet.addAnimation(alphaAnimation)
        animationSet.addAnimation(scaleAnimation)
        animationSet.duration = 5000
        tv_animator_view.startAnimation(animationSet)
    }

Configure la colección AnimationSet por código dinámico, coloque la animación requerida en ella, el efecto es el mismo

 

 

Se reproducen varias animaciones en secuencia :

La idea de la reproducción secuencial es utilizar el método de retardo en xml para especificar el retardo de ejecución de la animación a través de startOffset

como:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <alpha android:fromAlpha="0"
           android:toAlpha="1"
           android:duration="3000"
           android:fillAfter="true">
    </alpha>

    <!--第2个动画延迟3000毫秒-->
    <rotate
            android:startOffset="3000"
            android:fromDegrees="0"
            android:toDegrees="180"
            android:pivotY="150"
            android:pivotX="150"
            android:duration="3000"
            android:fillAfter="true">
    </rotate>
    
</set>

 

El uso de la configuración de carga es el mismo, por lo que no lo publicaré

 

Use el código para establecer la secuencia, supervise la finalización de la primera animación y luego realice la segunda animación

private fun animationOrder(){
        val rotateAnimation = RotateAnimation(0F, 180F, 150F, 150F)
        rotateAnimation.fillAfter = true
        rotateAnimation.duration = 5000
        rotateAnimation.setAnimationListener(object :Animation.AnimationListener{
            override fun onAnimationRepeat(animation: Animation?) {
                //动画重复
            }

            override fun onAnimationEnd(animation: Animation?) {
                //动画结束
                val alphaAnimation = AlphaAnimation(1.0F, 0F)
                alphaAnimation.fillAfter = true
                alphaAnimation.duration = 5000
                tv_animator_view.startAnimation(alphaAnimation)
            }

            override fun onAnimationStart(animation: Animation?) {
                //动画开始

            }

        })
        tv_animator_view.startAnimation(rotateAnimation)
    }

 

 

======= 【layoutAnimation】 ==========

Actúe en ViewGroup, especifique una animación para un ViewGroup, todos sus elementos secundarios tendrán este efecto de animación cuando salgan de fábrica

Por ejemplo, cuando se especifica RecycleView, cada elemento tendrá

Por ejemplo, cuando se especifica ViewGroup, cada vista secundaria tendrá

Primero, cree layoutAnimation: anim / layout_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                 android:delay="1"
                 android:animationOrder="random"
                 android:animation="@anim/alpha_ani">

    <!--
            delay: 每个子View时间间隔 如果有多个子view的话,如果设定的动画周期是 duration = 1000毫秒,
                    如果 delay=0.1,则下一个子View 会在100(duration * delay)毫秒执行动画

            animationOrder:子view经常顺序,normal是最前面的先进来,
                                            reverse是最后的先进来
                                            random 正看英文就知道。。。。哈哈

            顺序就是View.getChildView(index)  里面的这个index
    -->
</layoutAnimation>

Crear diseño Animación: anim / alpha.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:fillAfter="true">

    <!--透明
        fromAlpha:开始时透明度 0.0- 1.0   0.0全透明  1.0不透明
        toAlpha: 结束时透明度 0.0- 1.0
        duration:动画持续时间 单位 毫秒
        fillAfter:动画结束后是否停留在结束位置,true停留
        -->
    <alpha android:fromAlpha="0"
           android:toAlpha="1"
           android:duration="5000"
    >
    </alpha>

</set>

 

Archivo de diseño de diseño principal:

<android.support.constraint.ConstraintLayout
            android:id="@+id/tv_animator_contain"
            android:layout_width="0dp"
            android:layout_height="300px"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:layoutAnimation="@anim/layout_animation"
            android:visibility="invisible"
    >

        <TextView
                android:id="@+id/tv_animator_view"
                android:layout_width="300px"
                android:layout_height="300px"
                android:background="@color/color_00a3f3"
                android:text="目标动画1"
                android:textColor="@color/color_7e4513"
                android:gravity="center"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toLeftOf="@id/tv_animator_view2"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintHorizontal_chainStyle="spread"/>


        <TextView
                android:id="@+id/tv_animator_view2"
                android:layout_width="300px"
                android:layout_height="300px"
                android:background="@color/color_00a3f3"
                android:text="目标动画1"
                android:textColor="@color/color_7e4513"
                android:gravity="center"
                app:layout_constraintLeft_toRightOf="@id/tv_animator_view"
                app:layout_constraintRight_toLeftOf="@id/tv_animator_view3"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintHorizontal_chainStyle="spread"/>

        <TextView
                android:id="@+id/tv_animator_view3"
                android:layout_width="300px"
                android:layout_height="300px"
                android:background="@color/color_00a3f3"
                android:text="目标动画1"
                android:textColor="@color/color_7e4513"
                android:gravity="center"
                app:layout_constraintLeft_toRightOf="@id/tv_animator_view2"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintHorizontal_chainStyle="spread"/>

    </android.support.constraint.ConstraintLayout>

 

¡Nota! !   La  visibilidad del diseño principal = invisible, cuando el diseño principal se vuelve visible, se mostrarán las tres vistas secundarias

Por supuesto, la forma que aparece es en forma de animación. . .

Llamar en código:

private fun layoutAnimation() {
        tv_animator_contain.visibility = View.VISIBLE
    }

Simplemente muestre el diseño principal y todas las vistas secundarias aparecerán con efectos de animación. . . .

Tampoco puede establecer el diseño en el diseño principal, a través de  LayoutAnimationController

Directamente en el código:

private fun layoutAnimation() {
        val loadAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha_ani)
        val animationController = LayoutAnimationController(loadAnimation)
        animationController.delay = 0.1F
        animationController.order = LayoutAnimationController.ORDER_NORMAL
        tv_animator_contain.layoutAnimation = animationController
        tv_animator_contain.visibility = View.VISIBLE
    }

¡Nota! ! ! ! ! ! !

El código se refiere a  alpha_ani.xml , que se refiere directamente al archivo de animación, no a   layoutAnimation 

 

================== [ Animación de cuadros ] =========================

En primer lugar, la animación del cuadro es similar a la reproducción de video: muestra 26 imágenes en un segundo y el efecto que ve a simple vista es el video.

La animación de cuadro cargará todas las imágenes en la memoria a la vez y luego mostrará la siguiente imagen cada vez que se establezca la duración. . .

¡No recomendado! ! ! ¡Porque consume memoria! ! ! ! ! !

Primero, cree una animación de cuadros, que se encuentra en el directorio dibujable. . .

Luego seleccione lista de animaciones

 

luego 

 

Usar en el control:

    /**
     *      帧动画
     * */
    private fun startFrameAni() {
        //先设置
        tv_animator_view.setBackgroundResource(R.drawable.frame_animation)
        //再获取  强转成 AnimationDrawable
        val background = tv_animator_view.background as AnimationDrawable
        //开启动画
        background.start()
    }

Nuevamente, si hay demasiadas imágenes, esto conducirá fácilmente a OOM

Si tiene que usar la animación de cuadros, puede poner todos los ID del dibujable que necesita en una Lista

Luego, escriba un temporizador usted mismo (por ejemplo, use Handler), cada pocos segundos, obtenga el dibujable a través del ID para mostrar una imagen, para evitar cargar todas las imágenes en la memoria a la vez. . . .

Todo bien. . . . . . Aqui esta aqui

 

 

El siguiente artículo está escrito: animación de atributos

El código anterior no es un problema en la prueba profesional ,,,, si hay un problema, deje un mensaje para corregirlo, ¡gracias! ! ! !

 

Supongo que te gusta

Origin blog.csdn.net/Leo_Liang_jie/article/details/90752748
Recomendado
Clasificación