Android-动画学习

1、动画分类

  • 传统动画(帧动画、补间动画)
  • 3.0后的属性动画

2、动画-传统动画

    2.1、帧动画

            ①描述:帧动画是将一张张图片串联起来播放,从视觉上达到动画效果
            ②实例:京东的加载动画
               
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/gif1" android:duration="100"/>
    <item android:drawable="@mipmap/gif2" android:duration="100"/>
    <item android:drawable="@mipmap/gif3" android:duration="100"/>
    <item android:drawable="@mipmap/gif4" android:duration="100"/>
</animation-list>

    2.2、补间动画

            ①alpha(淡入淡出)

            ②translate(位移)

            ③rotate(旋转)

            ④scale(放大缩小)

        实例:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:fromAlpha="0.8"
        android:toAlpha="0" />
    <rotate
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
    <scale
        android:fromXScale="0"
        android:fromYScale="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1" />
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="1"
        android:toYDelta="1" />
</set>

3、属性动画

    3.1、出现的原因
        传统动画的缺点:

            a)作用对象只是View(如只想操作视图的颜色属性)

            b)没有改变View的属性,只是改变了视觉效果

            c)动画效果过于单一

    3.2、特点
  • 作用对象为任意java对象
  • 动画效果不只是4种变换
    3.3、工作原理

        


        属性动画有两个非常重要的类:ValueAnimator、ObjectAnimator

        他们的关系如图:

        

        相关类:

类名用途
ValueAnimator属性动画主要的计时器,也计算动画后的属性的值,动画的执行类
ObjectAnimator  ValueAnimator的一个子类,允许你设置一个目标对象和对象的属性进行动画,动画的执行类
AnimatorSet提供组织动画的结构,使它们能相关联得运行,用于控制一组动画的执行
AnimatorInflater 用户加载属性动画的xml文件
Evaluators 属性动画计算器,告诉了属性动画系统如何计算给出属性的值
Interpolators动画插入器,定义动画的变化率
    3.4、用法
        3.4.1、ValueAnimator

                ①原理:属性动画的机制是通过不断对值进行操作实现的,而初始值和结束值之间的动画过度就是由ValueAnimator这个类负责计算的,它的内部是使用时间循环的机制。ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等

                ②方法

                    ValueAnimator.ofInt() 初始值从整数过度到结束值

                    ValueAnimator.ofFloat()  初始值从浮点数过度到结束值

                    ValueAnimator.ofObject()  初始值从对象形式过度到结束值

                ③实例

                    一个View 4秒从原先宽度变到200的一个动画

                    a)代码方式

        ValueAnimator valueAnimator = ValueAnimator.ofInt(view.getLayoutParams().width, 200);
        valueAnimator.setDuration(4000);
        valueAnimator.setStartDelay(500);
        // 设置动画延迟播放时间
        valueAnimator.setRepeatCount(0);
        // 设置动画重复播放次数 = 重放次数+1
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int currentValue= (Integer) valueAnimator.getAnimatedValue();
                view.getLayoutParams().width=currentValue;
                view.requestLayout();
            }
        });
        valueAnimator.start();

                    b)xml方式

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:repeatCount="0"
    android:repeatMode="restart"
    android:valueFrom="0"
    android:valueTo="200"
    android:valueType="intType"></animator>
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.set_animation);  
// 载入XML动画
animator.setTarget(view);  
// 设置动画对象
animator.start();  
// 启动动画

                ④特殊ValueAnimator.ofObject()

                    1、估值器(TypeEvaluator

                            插值器(Interpolator)决定值的变化模式(匀速、加速)

                              估值器(TypeEvaluator)决定值的具体变化数值

                    2、ValueAnimator.ofFloat()原理

                            其实是系统内置了一个 FloatEvaluator估值器,内部实现了初始值与结束值 以浮点型的过渡逻辑

public class FloatEvaluator implements TypeEvaluator {
    /**
     * 重写evaluate
     * @param fraction 表示动画完成度(根据它来计算当前动画的值)
     * @param startValue 动画的初始值
     * @param endValue 动画的结束值
     * @return
     */
    public Object evaluate(float fraction, Object startValue, Object endValue) {  

        float startFloat = ((Number) startValue).floatValue();  
        
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);  
        // 初始值 过渡 到结束值 的算法是:
        // 1. 用结束值减去初始值,算出它们之间的差值
        // 2. 用上述差值乘以fraction系数
        // 3. 再加上初始值,就得到当前动画的值
    }  
}

                    3、ValueAnimator.ofObject() 从一个点到另一个点移动实例

public class Point {
    private float x;
    private float y;
    
    public Point(float x, float y) {
        this.x = x;
        this.y = y;
    }
    public float getX() {
        return x;
    }
    public float getY() {
        return y;
    }
}
public class PointEvaluator implements TypeEvaluator {
    
    @Override
    public Object evaluate(float fraction, Object startValue, Object endValue) {

        // 将动画初始值startValue 和 动画结束值endValue 强制类型转换成Point对象
        Point startPoint = (Point) startValue;
        Point endPoint = (Point) endValue;
        
        float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());
        float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());
        
        // 将计算后的坐标封装到一个新的Point对象中并返回
        Point point = new Point(x, y);
        return point;
    }

}

public class MyView extends View {
    // 设置需要用到的变量
    public static final float RADIUS = 70f;// 圆的半径 = 70
    private Point currentPoint;// 当前点坐标
    private Paint mPaint;// 绘图画笔
    

    // 构造方法(初始化画笔)
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 初始化画笔
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.BLUE);
    }

    // 复写onDraw()从而实现绘制逻辑
    // 绘制逻辑:先在初始点画圆,通过监听当前坐标值(currentPoint)的变化,每次变化都调用onDraw()重新绘制圆,从而实现圆的平移动画效果
    @Override
    protected void onDraw(Canvas canvas) {
        // 如果当前点坐标为空(即第一次)
        if (currentPoint == null) {
            currentPoint = new Point(RADIUS, RADIUS);
            // 创建一个点对象(坐标是(70,70))

            // 在该点画一个圆:圆心 = (70,70),半径 = 70
            float x = currentPoint.getX();
            float y = currentPoint.getY();
            canvas.drawCircle(x, y, RADIUS, mPaint);

            // 步骤1:创建初始动画时的对象点  & 结束动画时的对象点
            Point startPoint = new Point(RADIUS, RADIUS);// 初始点为圆心(70,70)
            Point endPoint = new Point(700, 1000);// 结束点为(700,1000)

            // 步骤2:创建动画对象 & 设置初始值 和 结束值
            ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);

            // 步骤3:设置动画参数
            anim.setDuration(5000);
            // 设置动画时长

            // 步骤3:通过 值 的更新监听器,将改变的对象手动赋值给当前对象
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    currentPoint = (Point) animation.getAnimatedValue();
                    // 将每次变化后的坐标值(估值器PointEvaluator中evaluate()返回的Piont对象值)到当前坐标值对象(currentPoint)
                    // 从而更新当前坐标值(currentPoint)

            // 步骤4:每次赋值后就重新绘制,从而实现动画效果
                    invalidate();
                    // 调用invalidate()后,就会刷新View,即才能看到重新绘制的界面,即onDraw()会被重新调用一次
                    // 所以坐标值每改变一次,就会调用onDraw()一次
                }
            });

            anim.start();
            // 启动动画

        } else {
           
            // 在该点画一个圆:圆心 = (30,30),半径 = 30
            float x = currentPoint.getX();
            float y = currentPoint.getY();
            canvas.drawCircle(x, y, RADIUS, mPaint);
        }
    }
}



        3.4.2、ObjectAnimator

            ① ValueAnimator与ObjectAnimator区别

  • ValueAnimator 类是先改变值,然后 手动赋值 给对象的属性从而实现动画;是 间接对对象属性进行操作;
  • ObjectAnimator 类是先改变值,然后 自动赋值 给对象的属性从而实现动画;是 直接对对象属性进行操作;

            ② 使用方法

                a)代码方式 

        ObjectAnimator anim = ObjectAnimator.ofFloat(object, property, values);
        anim.setDuration(500);// 设置动画运行的时长
        anim.setStartDelay(500);// 设置动画延迟播放时间
        anim.setRepeatCount(0);// 设置动画重复播放次数 = 重放次数+1
        anim.setRepeatMode(ValueAnimator.RESTART);// 设置重复播放动画模式
        anim.start();// 启动动画

                b)xml方式

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

            ③ 实现补间动画四种基本变化(平移、旋转、缩放 、透明度

        ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(view, "alpha", 0.8f, 0f);//逐渐透明
        ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(view, "scaleX", 1f, 3f);//X轴方向缩放到3倍
        ObjectAnimator translateAnim = ObjectAnimator.ofFloat(view, "translationX", view.getTranslationX(), 200,view.getTranslationX());//X轴平移
        ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);//360度旋转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值