我的自定义View学习笔记(六)—— 属性动画

  • 这个一个系列,本系列讲的都是本人自定义 View 的学习笔记。目的是加深影响,便于在以后工作中遇到相关问题的时候,能够有个印象知道到哪里去寻找答案。
  • 这是我学习扔物线大神的自定义 View 教程,自己记录的笔记。链接在这里HenCoder,强烈推荐大家去原地址学习,毕竟我写的笔记只是针对我个人的口味而言的,用词和对概念的理解不一定有扔物线大神准确。
  • 我再发一次地址:https://hencoder.com

1、ViewPropertyAnimator

  • 使用方式:View.animate() 后面直接跟着 translationX() 等方法
view.animate().translationX(500);  
  • 动画的方式有:
    image
    View 的每个方法都对应了 ViewPropertyAnimator 的两个方法,其中一个是带有 -By 后缀的。-By() 后缀的是增量版本的方法,是在原基础上增加多少

2、ObjectAnimator

2.1 使用方式

  • 如果是自定义控件,需要添加 setter / getter 方法
    • 其中需要着重理解一下 setter/getter 方法
    • ObjectAnimator.ofXXX() 方法时根据 xxx 去 View 中查找对应的动画方法执行对应的动画
    • xxx 就是 getter/setter 的方法名
    • 自定义控件中需要在 setter 方法中执行 invalidate(); 方法强制 View 重绘,去执行 draw() 方法
  • 用 ObjectAnimator.ofXXX() 创建 ObjectAnimator 对象
  • 用 start() 方法执行动画
public class SportsView extends View {  
    float progress = 0;

    ......

    // 创建 getter 方法
    public float getProgress() {
        return progress;
    }

    // 创建 setter 方法
    public void setProgress(float progress) {
        this.progress = progress;
        invalidate();
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        ......

        canvas.drawArc(arcRectF, 135, progress * 2.7f, false, paint);

        ......
    }
}

......

// 创建 ObjectAnimator 对象
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "progress", 0, 65);  
// 执行动画
animator.start();  

3、通用功能

3.1 setDuration(int duration) 设置动画时长

  • 单位是毫秒
// imageView1: 500 毫秒
imageView1.animate()  
        .translationX(500)
        .setDuration(500);

3.2 setInterpolator(Interpolator interpolator) 设置插值器

  • Interpolator 其实就是速度设置器。你在参数里填入不同的 Interpolator ,动画就会以不同的速度模型来执行。
imageView1.animate()  
        .translationX(500)
        .setInterpolator(new LinearInterpolator());

  • 具体的插值器的类型使用时自己去查就够了
  • 自定义插值器 PathInterpolator
    • 用这个 Interpolator 你可以定制出任何你想要的速度模型。定制的方式是使用一个 Path 对象来绘制出你要的动画完成度 / 时间完成度曲线。
      image
Path interpolatorPath = new Path();

...

// 先以「动画完成度 : 时间完成度 = 1 : 1」的速度匀速运行 25%
interpolatorPath.lineTo(0.25f, 0.25f);  
// 然后瞬间跳跃到 150% 的动画完成度
interpolatorPath.moveTo(0.25f, 1.5f);  
// 再匀速倒车,返回到目标点
interpolatorPath.lineTo(1, 1);  
- 这条 Path 描述的其实是一个 y = f(x) (0 ≤ x ≤ 1) (y 为动画完成度,x 为时间完成度)的曲线,否则FC
    - 同一段时间完成度上不能有两段不同的动画完成度(同一时间内不能有两种动画)
    - 每一个时间完成度的点上都必须要有对应的动画完成度(动画必须是连续的)

4、设置监听器

  • 给动画设置监听器,监听动画的执行情况并在需要的时刻进行制定的操作

4.1 ViewPropertyAnimator.setListener() / ObjectAnimator.addListener()

  • 这两个方法的名称不一样,可以设置的监听器数量也不一样,但它们的参数类型都是 AnimatorListener,所以本质上其实都是一样的。 AnimatorListener 共有 4 个回调方法
  • 4.1.1 onAnimationStart(Animator animation)
    • 动画开始时,被调用
  • 4.1.2 onAnimationEnd(Animator animation)
    • 动画结束时,被调用
  • 4.1.3 onAnimationCancel(Animator animation)
    • 动画被取消时调用。动画被取消,依旧会调用 onAnimationEnd() 方法。而且 onAnimationCancel() 会先于 onAnimationEnd() 被调用。
  • 4.1.4 onAnimationRepeat(Animator animation)
    • setRepeatMode() / setRepeatCount() 或 repeat() 方法重复执行时,这个方法被调用
    • ViewPropertyAnimator 不支持重复,所以这个方法对 ViewPropertyAnimator 相当于无效

4.2 ViewPropertyAnimator.setUpdateListener() / ObjectAnimator.addUpdateListener()

  • 这两个方法虽然名称和可设置的监听器数量不一样,但本质其实都一样的,它们的参数都是 AnimatorUpdateListener。它只有一个回调方法
  • onAnimationUpdate(ValueAnimator animation)
    • 当动画的属性更新时(不严谨的说,即每过 10 毫秒,动画的完成度更新时),这个方法被调用

4.3 ObjectAnimator.addPauseListener()

  • 监听暂停的方法

4.4 ViewPropertyAnimator.withStartAction/EndAction()

  • 这两个方法是 ViewPropertyAnimator 的独有方法
  • 和 set/addListener() 中回调的 onAnimationStart() / onAnimationEnd() 相比起来的不同主要有两点
    • withStartAction() / withEndAction() 是一次性的,在动画执行结束后就自动弃掉了,就算之后再重用 ViewPropertyAnimator 来做别的动画,用它们设置的回调也不会再被调用。而 set/addListener() 所设置的 AnimatorListener 是持续有效的,当动画重复执行时,回调总会被调用。
    • withEndAction() 设置的回调只有在动画正常结束时才会被调用,而在动画被取消时不会被执行。这点和 AnimatorListener.onAnimationEnd() 的行为是不一致的。

练习代码

  • 我本来想传一下代码,发现CSDN现在传资源必须设置下载积分,那我就不骗积分了,有需要的可以评论,我传到git上。其实直接用原链接中的练习代码就可以。

猜你喜欢

转载自blog.csdn.net/Android_03/article/details/84072809