动画

Matrix

作用就是坐标映射,转成实际的坐标位置。
基本变换有4种: 平移(translate)、缩放(scale)、旋转(rotate) 和 错切(skew)。

帧动画

原理:就是将一张张单独的图片连贯的进行播放
缺点:这种动画效果单一,性能差,占用内存高

补间动画

比帧动画性能好,效果多,动画更加连贯。

间动画仅仅是对 View 在视觉效果上做了移动、缩放、旋转和淡入淡出的效果,其实并没有真正改变 View 的属性。
补间动画的核心本质就是在一定的持续时间内,不断改变 Matrix 变换,并且不断刷新的过程。invalidate

补间动画所操作的 Matrix,其实是借用了它父容器的一个叫 mChildTransformation 的属性 ( 里面有 Matrix ),通过 getChildTransformation 获得。
也就是说,一个 ViewGroup 中,无论它有几个子 View 都好,在这些子 View 播放补间动画的时候,都是共用同一个 Transformation 对象的(也就是共用一个 Matrix ),这个对象放在 ViewGroup 里面。

属性动画

功能非常强大,弥补了之前补间动画的一些缺陷,几乎是可以完全替代掉补间动画了。

优点:可以自定义动画,实现复杂动画效果。最重要的是可以改变属性动画的值,不会影响动画执行后的位置正常使用
其实就是在一定的时间间隔内,通过不断地对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在属性上的动画效果。
对于属性动画来说,尤其需要注意的是操作的属性需要有 set 和 get 方法,不然你的 ObjectAnimator 操作就不会生效。

属性动画所影响的 Matrix,是在 View 的 mRenderNode 中的 stagingProperties 里面的,这个 Matrix 在每个 View 之间都是独立的,所以可以各自保存不同的变换状态。

性能分析

属性动画操作的是对象的实例属性,例如translationX,然后反射调用set,get方法,多个属性动画同时执行,会频繁反射调用类方法,降低性能。
属性动画虽然会反射,但是也会用hashMap缓存反射过的method,进行复用。

补间动画只产生了一个动画效果,其真实的坐标并没有发生改变,是效果一直在发生变化,没有频繁反射调用方法的耗费性能操作。
不过补间动画执行完成后,不回置动画效果,对于事件点击容易产生困扰。而属性动画因为操作了类的属性,也就是View的top,left,height,width等,没有补间动画的问题

ValueAnimator 类 & ObjectAnimator 类,二者的区别在于:

ValueAnimator 类

是先改变值,然后 手动赋值 给对象的属性从而实现动画;是 间接 对对象属性进行操作;而 ValueAnimator 类本质上是一种 改变值 的操作机制。

只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果

ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float currentValue = (float) animation.getAnimatedValue();
        Log.d("TAG", "cuurent value is " + currentValue);
    }
});
anim.start();

ValueAnimator.ofXXX

实际使用:根据计算出来的值不断改变控件的高度,实现控件展开和折叠效果。

ObjectAnimator 类

是先改变值,然后 自动赋值 给对象的属性从而实现动画;是 直接 对对象属性进行操作;可以理解为:ObjectAnimator 更加智能、自动化程度更高。

当ViewGroup分派事件的时候,会正确的将当前触摸坐标,转换成矩阵变化后的坐标

继承与ValueAnimator

原理:根据已执行动画时间百分比计算插值分数,用插值分数计算估算值,更新属性值。

//设置要执行动画效果的view,要改变的属性值,开始值,结束值
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
//动画时间
animator.setDuration(5000);
animator.start();

ObjectAnimator.ofXXX

根据传入的属性名,去寻找属性名对应的get和set方法。通过反射,通过hashmap缓存反射过的method方法。

常用属性

  • translationX和translationY:这些属性控制View所在的位置,作为由其布局容器设置的左侧和顶部坐标的增量。
  • rotation,rotationX和rotationY:这些属性控制2D(rotation属性)中的旋转和围绕轴点的3D。
  • scaleX和scaleY:这些属性控制View围绕其轴心点的2D缩放。
  • pivotX和pivotY:这些属性控制枢轴点的位置,围绕该枢轴点进行旋转和缩放变换。默认情况下,轴心点位于对象的中心。
  • x和y:这些是简单的实用程序属性,用于描述View在其容器中的最终位置,作为左值和顶值以及translationX和translateY值的总和。
  • alpha:表示视图上的Alpha透明度。默认情况下,此值为1(不透明),值为0表示完全透明(不可见)。

实际运用:用AnimatorSet内传ObjectAnimator,对身份证进行放缩位移操作

组合动画 AnimatorSet

实现组合动画功能主要需要借助AnimatorSet这个类,这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:

ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(5000);
animSet.start();

Animator监听器

ObjectAnimator是继承自ValueAnimator的,而ValueAnimator又是继承自Animator的,因此不管是ValueAnimator还是ObjectAnimator都是可以使用addListener()这个方法的。另外AnimatorSet也是继承自Animator的,因此addListener()这个方法算是个通用的方法。

anim.addListener(new AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
    }
 
    @Override
    public void onAnimationRepeat(Animator animation) {
    }
 
    @Override
    public void onAnimationEnd(Animator animation) {
    }
 
    @Override
    public void onAnimationCancel(Animator animation) {
    }
});

适配器对象,单独重写onAnimationEnd


anim.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
    }
});

Evaluator

通过计算告知动画系统如何从初始值过度到结束值

ValueAnimator.ofFloat(),系统内置了一个FloatEvaluator,实现了TypeEvaluator接口,然后重写evaluate()方法。

public class FloatEvaluator implements TypeEvaluator {
    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}
  • 第一个参数fraction非常重要,这个参数用于表示动画的完成度的,我们应该根据它来计算当前动画的值应该是多少
  • 第二第三个参数分别表示动画的初始值和结束值。那么上述代码的逻辑就比较清晰了,用结束值减去初始值,算出它们之间的差值,然后乘以fraction这个系数,再加上初始值,那么就得到当前动画的值了。

Interpolator

它的主要作用是可以控制动画的变化速率

接口TimeInterpolator
仅有这个方法float getInterpolation(float input);

input这个参数的值会随着动画的运行而不断变化,不过它的变化是非常有规律的,就是根据设定的动画时长匀速增加,变化范围是0到1。也就是说当动画一开始的时候input的值是0,到动画结束的时候input的值是1,而中间的值则是随着动画运行的时长在0到1之间变化的。

Evaluator中fraction和input的关系?

input的值决定了fraction的值。input的值是由系统经过计算后传入到getInterpolation()方法中的,然后我们可以自己实现getInterpolation()方法中的算法,根据input的值来计算出一个返回值,而这个返回值就是fraction了。

系统默认的Interpolator其实就是一个先加速后减速的Interpolator,对应的实现类就是AccelerateDecelerateInterpolator。
调用Animator的setInterpolator()方法

设置Interpolator

private void startAnimation() {
    Point startPoint = new Point(getWidth() / 2, RADIUS);
    Point endPoint = new Point(getWidth() / 2, getHeight() - RADIUS);
    ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            currentPoint = (Point) animation.getAnimatedValue();
            invalidate();
        }
    });
    //设置Interpolator
    anim.setInterpolator(new BounceInterpolator());
    anim.setDuration(3000);
    anim.start();
}

安卓有很多内置的Interpolator,我们也可以自定义Interpolator


public class DecelerateAccelerateInterpolator implements TimeInterpolator{
 
    @Override
    public float getInterpolation(float input) {
        float result;
        if (input <= 0.5) {
            result = (float) (Math.sin(Math.PI * input)) / 2;
        } else {
            result = (float) (2 - Math.sin(Math.PI * input)) / 2;
        }
        return result;
    }
 

ViewPropertyAnimator

为View的动画操作提供一种更加便捷的用法

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 0f);
animator.start();

用ViewPropertyAnimator实现

textview.animate().alpha(0f);

textview.animate().x(500).y(500);

textview.animate().x(500).y(500).setDuration(5000)
        .setInterpolator(new BounceInterpolator());

https://blog.csdn.net/guolin_blog/article/details/44171115

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 【Android 动画】 动画分类补间动画(Tween动画)帧动画(Frame 动画)属性动画(Property ...
    Rtia阅读 6,139评论 1 38
  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 2,705评论 0 10
  • 动画基础概念 动画分类 Android 中动画分为两种,一种是 Tween 动画、还有一种是 Frame 动画。 ...
    Rtia阅读 1,226评论 0 6
  • 本笔记的原文本链接 Property Animation Overview 属性动画总览 The property...
    Jaesoon阅读 1,098评论 2 3
  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 1,915评论 0 10