个人技术分享

和帧动画不同,帧动画 是通过连续播放图片来模拟动画效果,而补间动画开发者只需指定动画开始,以及动画结束"关键帧", 而动画变化的"中间帧"则由系统计算并补齐!

Andoird所支持的补间动画效果有如下这五种,或者说四种吧,第五种是前面几种的组合而已~

AlphaAnimation:透明度渐变效果,创建时许指定开始以及结束透明度,还有动画的持续 时间,透明度的变化范围(0,1),0是完全透明,1是完全不透明;对应 <alpha/> 标签! ScaleAnimation:缩放渐变效果,创建时需指定开始以及结束的缩放比,以及缩放参考点, 还有动画的持续时间;对应 <scale/> 标签! TranslateAnimation:位移渐变效果,创建时指定起始以及结束位置,并指定动画的持续 时间即可;对应 <translate/> 标签! RotateAnimation:旋转渐变效果,创建时指定动画起始以及结束的旋转角度,以及动画 持续时间和旋转的轴心;对应 <rotate/> 标签 AnimationSet:组合渐变,就是前面多种渐变的组合,对应 <set/> 标签。

这里我们先介绍AlphaAnimation、ScaleAnimation、TranslateAnimation、RotateAnimation。

如下是我们用到的类:

android.view.animation.Animation

Animation类是安卓所提供的实现基础动画效果的类,一共有四种不同的效果:半透明渐变、旋转、缩放和移动。可以说所有的复杂动画都可以由这几种基本效果组合而成。而实现这四种效果也非常简单。

android.view.animation.AnimationUtils

AnimationUtils类是Android系统中的动画工具类,提供了控制View对象的一些工具。

android.view.animation.AlphaAnimation

通过改变View的透明度来实现动画效果。

android.view.animation.RotateAnimation

RotateAnimation类是Android系统中的旋转变化动画类,用于控制View对象的旋转动作,该类继承于Animation类。

android.view.animation.ScaleAnimation

Android系统中的尺寸变化动画类,用于控制View对象的尺寸变化,该类继承于Animation类。

android.view.animation.TranslateAnimation

TranslateAnimation类是Android系统中的位置变化动画类,用于控制View对象的位置变化,该类继承于Animation类。TranslateAnimation类中的很多方法都与Animation类一致,该类中最常用的方法便是TranslateAnimation构造方法。

AlphaAnimation、RotateAnimation、ScaleAnimation、TranslateAnimation都继承Animation,因此他们都可以使用Animation的方法。



方法 描述

AlphaAnimation(float fromAlpha, float toAlpha)

AlphaAnimation构造函数

RotateAnimation(float fromDegrees, float toDegrees,

int pivotXType, float pivotXValue, int pivotYTyoe, float pivotYValue)

RotateAnimation构造函数

ScaleAnimation(float fromX, float toX, float fromY, float toY,

int pivotXType, float pivotXValue, int pivotYTyoe, float pivotYValue)

ScaleAnimation构造函数

TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,

int fromYType, float fromYValue, int toYType, float toYValue)

TranslateAnimation构造函数

void addAnimation(Animation a)

添加定义好的动画效果

void setDuration(long durationMillis)

设置播放时长(毫秒)

void setRepeatCount(int repeatCount)

设置重放次数

void setRepeatMode(int repeatMode)

设置重放模式(reverse表示倒序回放,restart表示从头播放)

void setInterpolator(Interpolator i)

设置插值器

void setFillAfter(boolean fillAfter)

控件动画结束时是否保持动画最后的状态

void setFillBefore(boolean fillBefore)

控件动画结束时是否还原到开始动画前的状态

void setStartOffset(long startOffset)

调用start函数之后等待开始运行的时间,单位为毫秒

void setAnimationListener(AnimationListener listener)

动画的事件监听



这里有一个差值器(interpolator)的概念,我们后续再介绍。

补间动画可以在xml文件中设置,也可以直接在代码中调用各自的类来设置。下面我们两种方法都练习一下。

首先我们在res文件先创建amin目录在分别创建alpha、rotate、scale、tranlslate.xml文件。



alpha.xml(透明度渐变效果)

属性解释:

fromAlpha :起始透明度 toAlpha:结束透明度 透明度的范围为:0-1,完全透明-完全不透明

<?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="2000" />


</set>

rotate.xml(旋转渐变效果)

属性解释:

fromDegrees/toDegrees:旋转的起始/结束角度

pivotX/pivotY:旋转的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的中心为中轴点进行旋转

repeatCount:旋转的次数,默认值为0,代表一次,假如是其他值,比如3,则旋转4次 另外,值为-1或者infinite时,表示动画永不停止

repeatMode:设置重复模式,默认restart,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成reverse,表示偶数次显示动画时会做方向相反的运动!

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


    <rotate
        android:fromDegrees="0"
        android:toDegrees="720"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:duration="2000" />
</set>

scale.xml(缩放渐变效果)

属性解释:

fromXScale/fromYScale:沿着X轴/Y轴缩放的起始比例 toXScale/toYScale:沿着X轴/Y轴缩放的结束比例 pivotX/pivotY:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的 中心为中轴点进行缩放

epeatCount:缩放的次数,默认值为0,代表一次,

repeatMode:设置重复模式,默认restart

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


    <scale
        android:fromXScale="1"
        android:toXScale="10"
        android:fromYScale="1"
        android:toYScale="10"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:duration="2000" />
</set>

translate.xml(位移渐变效果)

属性解释: fromXDelta/fromYDelta:动画起始位置的X/Y坐标 toXDelta/toYDelta:动画结束位置的X/Y坐标

epeatCount:位移的次数,默认值为0,代表一次,

repeatMode:设置重复模式,默认restart

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


    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="320"
        android:toYDelta="320"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:duration="2000" />
</set>

然后在activity_main.xml键入如下代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="MissingClass">


    <ImageView
        android:id="@+id/iv"
        android:src="@drawable/background"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:adjustViewBounds="true"
        android:maxHeight="300dp"
        android:maxWidth="300dp"/>


</RelativeLayout>

最后是Activity代码:

package com.example.animationdomo;


import androidx.appcompat.app.AppCompatActivity;


import android.os.Bundle;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;


public class MainActivity extends AppCompatActivity {


    private int count = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        ImageView imageView = findViewById(R.id.iv);


        //透明度
        Animation alphaAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha);


        //旋转
        Animation rotateAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate);


        //缩小
        Animation scaleAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.scale);


        //平移
        Animation translateAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.translate);


        //透明度从0到1
        AlphaAnimation alphaAnimation1 = new AlphaAnimation(0,1);
        alphaAnimation1.setDuration(2000);


        //旋转2圈
        RotateAnimation rotateAnimation1 = new RotateAnimation(0,720,
                Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
        rotateAnimation1.setDuration(2000);


        //放大10倍
        ScaleAnimation scaleAnimation1 = new ScaleAnimation(1f,10,1f,10,
                Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        scaleAnimation1.setRepeatCount(1);
        scaleAnimation1.setRepeatMode(Animation.REVERSE);
        scaleAnimation1.setDuration(2000);


        //平移
        TranslateAnimation translateAnimation1 = new TranslateAnimation(
                Animation.ABSOLUTE,0, Animation.RELATIVE_TO_PARENT,0.305f,
                Animation.ABSOLUTE,0, Animation.RELATIVE_TO_PARENT,0.305f);
        translateAnimation1.setRepeatCount(1);
        translateAnimation1.setRepeatMode(Animation.REVERSE);
        translateAnimation1.setDuration(2000);


        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                if(count == 0) {
                    imageView.startAnimation(alphaAnimation);
                    count = 1;
                }else if(count == 1){
                    imageView.startAnimation(rotateAnimation);
                    count = 2;
                }else if(count == 2){
                    imageView.startAnimation(scaleAnimation);
                    count = 3;
                }else if(count == 3){
                    imageView.startAnimation(translateAnimation);
                    count = 4;
                }else if(count == 4){
                    imageView.startAnimation(alphaAnimation1);
                    count = 5;
                }else if(count == 5){
                    imageView.startAnimation(rotateAnimation1);
                    count = 6;
                }else if(count == 6){
                    imageView.startAnimation(scaleAnimation1);
                    count = 7;
                }else if(count == 7){
                    imageView.startAnimation(translateAnimation1);
                    count = 0;
                }
            }
        });
    }
}

Domo代码:

Android动画介绍-补间动画(1)资源-CSDN文库