关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »深入理解 Android 动画 Interpolator 类的使用

    深入理解 Android 动画 Interpolator 类的使用

    2015-10-18 00:00:00 出处:烧饼的小院
    分享

    做过android动画的人对Interpolator应该不会陌生,这个类主要是用来控制android动画的执行速率,一般情况下,假如我们不设置,动画都不是匀速执行的,系统默认是先加速后减速这样一种动画执行速率。

    android通过Interpolator类来让我们自己控制动画的执行速率,还记得上一篇博客中我们使用属性动画实现的旋转效果吗?在不设置Interpolator的情况下,这个动画是先加速后减速,我们现在使用android系统提供的类LinearInterpolator来设置动画的执行速率,LinearInterpolator可以让这个动画匀速执行,我们来看一个案例,我们有两个Textview重叠放在一起,点击旋转按钮后这两个TextView同时执行旋转动画,不同的是一个设置了LinearInterpolator,而另外一个什么都没有设置,代码如下:

    LinearInterpolator ll = new LinearInterpolator();
    ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "rotation",
                        0f, 360f);
    animator.setInterpolator(ll);
    animator.setDuration(5000);
    animator.start();
    ObjectAnimator animator2 = ObjectAnimator.ofFloat(tv2, "rotation",
                        0f, 360f);
    animator2.setDuration(5000);
    animator2.start();

    效果图如下:

    这里写图片描述

    现在我们可以很清楚的看到这里的差异,一个TextView先加速后减速,一个一直匀速运动。

    这就引起了我的好奇,究竟LinearInterpolator做了什么,改变了动画的执行速率。这里我们就要看看源码了。

    当我们调用animator.setInterpolator(ll);的时候,调用的是ValueAnimator方法中的setInterpolator方法,源码如下:

        public void setInterpolator(TimeInterpolator value) {
            if (value != null) {
                mInterpolator = value;
            } else {
                mInterpolator = new LinearInterpolator();
            }
        }

    我们看到这里有一个mInterpolator变量,假如我们不执行这个方法,那么mInterpolator 的默认值是多少呢?

    我们找到了这样两行代码:

        // The time interpolator to be used if none is set on the animation
        private static final TimeInterpolator sDefaultInterpolator =
                new AccelerateDecelerateInterpolator();
    private TimeInterpolator mInterpolator = sDefaultInterpolator;

    这下明朗了,假如我们不设置,那么系统默认使用AccelerateDecelerateInterpolator,AccelerateDecelerateInterpolator又是什么呢?继续看源码:

    public class AccelerateDecelerateInterpolator extends BaseInterpolator
            implements NativeInterpolatorFactory {
        public AccelerateDecelerateInterpolator() {
        }
    
        @SuppressWarnings({"UnusedDeclaration"})
        public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
        }
    
        public float getInterpolation(float input) {
            return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
        }
    
        /** @hide */
        @Override
        public long createNativeInterpolator() {
            return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
        }
    }

    这里的一个核心函数就是getInterpolation,使用了反余弦函数,input传入的值在0-1之间,因此这里返回值的变化速率就是先增加后减少,对应的动画执行速率就是先增加后减速。有兴趣的童鞋可以使用MatLab来画一下这个函数的图像。而当我们实现了LinearInterpolator之后,情况发生了变化:

    public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
    
        public LinearInterpolator() {
        }
    
        public LinearInterpolator(Context context, AttributeSet attrs) {
        }
    
        public float getInterpolation(float input) {
            return input;
        }
    
        /** @hide */
        @Override
        public long createNativeInterpolator() {
            return NativeInterpolatorFactoryHelper.createLinearInterpolator();
        }
    }

    这里干净利落直接返回了input,没有经过任何计算。input返回的值是均匀的,因此动画得以匀速执行。

    看到这里,大家应该就明白了,假如我们想要控制动画的执行速率,应该重写getInterpolation方法就能实现。为了证实我们的猜想,我们继续看源码。

    大部分时候,我们使用的系统提供的各种各样的**Interpolator,比如上文说的LinearInterpolator,这些类都是继承自Interpolator,而Interpolator则实现了TimeInterpolator接口,我们来看看一个继承结构图:

    这里写图片描述

    那么这个终极大Boss TimeInterpolator究竟是什么样子呢?

    package android.animation;
    
    /**
     * A time interpolator defines the rate of change of an animation. This allows animations
     * to have non-linear motion, such as acceleration and deceleration.
     */
    public interface TimeInterpolator {
    
        /**
         * Maps a value representing the elapsed fraction of an animation to a value that represents
         * the interpolated fraction. This interpolated value is then multiplied by the change in
         * value of an animation to derive the animated value at the current elapsed animation time.
         *
         * @param input A value between 0 and 1.0 indicating our current point
         *        in the animation where 0 represents the start and 1.0 represents
         *        the end
         * @return The interpolation value. This value can be more than 1.0 for
         *         interpolators which overshoot their targets, or less than 0 for
         *         interpolators that undershoot their targets.
         */
        float getInterpolation(float input);
    }

    源码还是很简单的,只有一个方法,就是getInterpolation,看来没错,就是它了,假如我们想要自定义Interpolator,只需要实现TimeInterpolator接口的getInterpolation方法就可以了,getInterpolation方法接收的参数是动画执行的百分比,这个值是均匀的。

    我们来个简单的案例:

    public class TanInterpolator implements TimeInterpolator {
    
        @Override
        public float getInterpolation(float t) {
            return (float) Math.sin((t / 2) * Math.PI);
        }
    }

    在动画中使用:

    TanInterpolator tl = new TanInterpolator();
    ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "rotation", 0f, 360f);
    animator.setInterpolator(tl);
    animator.setDuration(5000);
    animator.start();

    咦?这是什么效果?这是一开始速度很大,然后逐渐减小到0的动画效果.

    原因如下:

    看下图,这是sin函数图象:

    这里写图片描述

    x取0-0.5PI,y值则为0-1,这一段曲线的斜率逐渐减小至0,这也是为什么我们的动画一开始执行很快,后来速度逐渐变为0.

    好了,看完这些,想必大家已经理解了这个类的使用了吧。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    SQL汉字转换为拼音的函数

    windows 7系统无法运行Photoshop CS3的解决方法

    巧用MySQL加密函数对Web网站敏感数据进行保护

    MySQL基础知识简介

    Windows7和WinXP下如何实现不输密码自动登录系统的设置方法介绍

    windows 7系统ip地址冲突怎么办?windows 7系统IP地址冲突问题的

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。