Android 弹性动画三种实现方式

**原文地址:http://blog.csdn.net/qq_34902522/article/details/77651799

前言###

现在的android开发提出的需求是越来越接近现实真实感,提高用户  
体验感。就拿动画效果来说,之前设计给的需求大都比较直接,缩放、  
旋转、移动等动画效果都执行完就结束了。现在的话,为了追求现实  
生活中的那种真实感,往往都会有一个回弹的效果,称之为弹性动画。

非弹性动画体验###

非弹性动画的效果图:  
普通缩放动画效果

我们来看一下实现该效果的代码:

private void onScaleAnimation(){
        ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageView,"scaleX",1.0f,1.8f);
        ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageView,"scaleY",1.0f,1.8f);
        AnimatorSet set =new AnimatorSet();
        set.setDuration(1000);
        set.playTogether(animatorX,animatorY);
        set.start();
    }
通过效果图,我们会觉得不real,我们想让他Q一点,有弹性效果  
那该怎么实现呢?往下看。

弹性动画的三种实现方式###

way 1####

通过interpolator(差值器)实现弹性效果。  
这里给大家安利一个关于差值器网站:

选择你所需要的差值器

在这个网站上可以在线看每种interpolator的效果,从而选择  
所需要的interpolator。这里我们选择scaling,library选  
择spring。如下图:
这里写图片描述
然后重写interpolator类,代码如下:  
public class SpringScaleInterpolator implements Interpolator {
    //弹性因数
    private float factor;

    public SpringScaleInterpolator(float factor) {
        this.factor = factor;
    }

    @Override
    public float getInterpolation(float input) {

        return (float) (Math.pow(2, -10 * input) * Math.sin((input - factor / 4) * (2 * Math.PI) / factor) + 1);
    }


}
接下来就是把我们重写的差值器设置进去,看代码:  
private void onScaleAnimationBySpringWayOne(){
//        ScaleAnimation animation =new ScaleAnimation(1.0f,1.8f,1.0f,1.8f);
//        animation.setDuration(1000);
//        animation.setInterpolator(new SpringScaleInterpolator(0.4f));
//        imageView.startAnimation(animation);
        ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageView,"scaleX",1.0f,1.8f);
        ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageView,"scaleY",1.0f,1.8f);
        AnimatorSet set =new AnimatorSet();
        set.setDuration(1000);
        set.setInterpolator(new SpringScaleInterpolator(0.4f));
        set.playTogether(animatorX,animatorY);
        set.start();

    }
这里重写的interpolator的构造方法中我穿的参数是因子,  
它的值越大,它回弹效果越慢。让我们来看看效果吧。
重写interpolator实现的回弹效果
确实达到了我们要的弹性效果,如果觉得弹性不够的话,可以修改  
弹性因数即可。这里我用的是属性动画,用补间动画设置自己  
重写的interpolator也是同样可以的。

way 2####

第二种实现弹性动画的方式是使用Facebook推出的rebound  
如何使用的呢?首先我们要在build.gradle中引入如下依赖:  
compile 'com.facebook.rebound:rebound:0.3.8'  
然后我们先上代码,根据代码来讲解使用:  
private void onScaleAnimationBySpringWayTwo(){
        SpringSystem springSystem = SpringSystem.create();
        Spring spring = springSystem.createSpring();
        spring.setCurrentValue(1.0f);
        spring.setSpringConfig(new SpringConfig(50,5));
        spring.addListener(new SimpleSpringListener(){
            @Override
            public void onSpringUpdate(Spring spring) {
                super.onSpringUpdate(spring);
                float currentValue = (float) spring.getCurrentValue();
                imageView.setScaleX(currentValue);
                imageView.setScaleY(currentValue);
            }
        });
        spring.setEndValue(1.8f);
    }
使用rebound我们需要初始化SpringSystem对象和Spring对象。  
通过Spring我们可以设置动画属性的初始值、结束值。  
Spring需要添加一个SpringListener接口,代码中我用的SimpleSpringListener  
是Springlistener的实现类。(ps:addListener这里如果new 一个SpringListener的话  
要重写全部的方法,没必要,需要哪个写哪个)。  
我们看下SpringListener接口的定义  
public interface SpringListener {

  /**
   * called whenever the spring is updated
   * @param spring the Spring sending the update
   */
  void onSpringUpdate(Spring spring);

  /**
   * called whenever the spring achieves a resting state
   * @param spring the spring that's now resting
   */
  void onSpringAtRest(Spring spring);

  /**
   * called whenever the spring leaves its resting state
   * @param spring the spring that has left its resting state
   */
  void onSpringActivate(Spring spring);

  /**
   * called whenever the spring notifies of displacement state changes
   * @param spring the spring whose end state has changed
   */
  void onSpringEndStateChange(Spring spring);
}
我们需要什么样的需求就重写对应方法就好。
上面的代码中有SpringConfig这个对象,通过看源码发现  
他的构造函数接受两个变量:1.tension(拉力)、2.friction(摩擦力)。  
作用是什么呢?很好理解tension拉力越大,弹性越大,friction  
摩擦力越大,弹性效果越小。默认的tension值,friction值如下:  
  public static SpringConfig defaultConfig = SpringConfig.fromOrigamiTensionAndFriction(40, 7);

下面让我们看下通过rebound实现的弹性效果是什么样的.
通过rebound实现弹性动画
弹性效果可以通过修改tension和friction的值来改变,大家可以试试。

way 3####

下面我们说一说最后一种实现方式。通过引入官方提供的SpringAnimation  
来实现。上面第二种方式我们是用的Facebook推出的框架,现在  
我们看看Google官方的效果吧。  
首先我们在build.gradle文件中引入依赖:  
compile 'com.android.support:support-dynamic-animation:25.3.1'
接下来上代码:
private void onScaleAnimationBySpringWayThree(){
        SpringAnimation animationX = new SpringAnimation(imageView, SpringAnimation.SCALE_X,1.8f);
        SpringAnimation animationY = new SpringAnimation(imageView, SpringAnimation.SCALE_Y,1.8f);
        animationX.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);
        animationX.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY);
        animationX.setStartValue(1.0f);

        animationY.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);
        animationY.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY);
        animationY.setStartValue(1.0f);

        animationX.start();
        animationY.start();
    }
这里面具体的一些用法,我就不细说了,可以参考:

SpringAnimation的使用

这个链接里面说的还挺详细的。那我们看下通过SpringAnimation  
实现的效果是怎么样的。
弹性动画实现通过SpringAnimation
同rebound,这边如果你对弹性动画的弹性效果不满意可以通过  
setStiffness()和setDampingRatio()方法来实现你想要的效果。  
注意哦,stiffness的值越小,弹性效果越好,弹时间越长。  
DampingRatio的值越大,弹性效果越差。

区别###

这三种方式都可以实现弹性效果,那到底选择什么方式呢,这里说一下  
rebound和SpringAnimation。SpringAnimation的话在对一个控件  
多个属性的动画效果设置比如一个view我既设置缩放动画又设置  
平移动画。就会会出现代码量多的问题,而rebound则相对好些。  
下面附上一张完整的效果图:
这里写图片描述
最后附上项目的demo,有需要的可以看看。  

弹性动画demo

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 本文参加#感悟三下乡,青春筑梦行#活动,本人承诺,文章内容为原创,且未在其他平台发表过。 明明都是一些小...
    01620a5339cc阅读 339评论 1 5
  • 钱是什么?是流动的水。谁能把水留住?放在地上,它流走了;放在容器里,会干涸;即使喝到肚子里,它还会溜走。既然留它不...
    duoduo_four阅读 146评论 0 1
  • 天气变得超级冷,我早就穿上了打底裤,不是厚的所以感觉超级冷。上海这会还在下着雨,八号就要立冬了,感觉要有好多衣服要...
    一颗小鸡蛋阅读 211评论 0 0