由浅入深带你看android 动画( 二)

这里接上一篇博客:http://blog.csdn.net/sunzhishuai/article/details/52863476 继续来说说android 动画,在上一篇博客中主要讲了android 动画的一些基本使用技巧,这里继续。

(一) Interpolator 的使用插值器的使用

所谓的插值器,就是根据动画时间的流失,来计算当前属性变化的百分比,android 已经实现了几种插值器,如AnticipateInterpolator ,LineInterpolator,效果这里就不说了,大家可以自己试验一下。什么叫根据动画时间的流失,来计算当前属性变化的百分比呢?这里看代码,我自定义了一个插值器,方法很简单实现Interpolator 接口即可。实现getinterpolation 方法

public class MyInterpolator implements android.view.animation.Interpolator {
    @Override
    public float getInterpolation(float input) {
        return 0;
    }
}

这里就一个参数 input 它的值由系统来给在[0,1] 之间。可以看到我返回的值为0;下面就使用这个插值器,代码如下:

mgirl = (ImageView) findViewById(R.id.iv_girl);
ObjectAnimator translationX = ObjectAnimator.ofFloat(mgirl, "TranslationX", 0, 500);
translationX.setDuration(2000).setInterpolator(new MyInterpolator());
translationX.start();

一个简单的平移动画,你会发现如果为们运行的话,是没有任何效果的,因为虽然系统根据时间流逝,input 不断变化,但是我们返回0的话 表示我们这个值始终不变啊,所以没有效果,那么如果我们不=直接把input 返回,你会发现根线性插值器是一样的效果。说到这你可能有点感觉了,就是把时间进行了多少的百分百,转换成属性变化的百分比嘛,对,插值器就是这么简单。 但是半分比自然是小于1咯,如果你大于1了,当然可以,单是灰出现,动画属性变化非常大,超出了我们设置的范围,变化200%或者更多。所以建议最后返回值<1. 这里你可以通过对input 做一些函数转化,实现特殊效果,无比sin函数 cos函数 ,为什么选这些,原因简单啊 他们的值域 都在0-1 范围内啊。

(二)TypeEvaluator 估值器

上篇文章我们已经见过它了,所谓估值器就是根据当前属性百分比的变化,来计算最后属性变化后的值的,一看就明白就是把interpolator 返回的值转换成最后属性的变化值啊,就那么简单。android 系统也为网们定义3种估值器,IntEvaluator FloatEvaluator colorIntEvaluator ,也就是说系统可以对这些值进行估计,你可以回想一下 我们的属性动画是不是我们没有制定估值器,但是系统也最后实现了这个属性的动画,因为系统会跟进你选择的动画种类去选择合适的估值器,单是当我们要对别的属性做动画时候就需要自己定义插值器了,上篇文章,我们已经做过了嘛,ObjectAnimatr.ofObject()方法我们就使用过了。这里在用ValueAnimator 来实现一下。由于前面说过了直接上代码了

public class Point {
    float x;
    float y;

    public Point(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public float getX() {
        return x;
    }

    public void setX(float x) {
        this.x = x;
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
    }

自定义的point 属性。

public class MyInterpolator implements android.view.animation.Interpolator {
    @Override
    public float getInterpolation(float input) {
        return input*input*input*input;
    }
}

自定义的插值器,x^4 作为转换函数,

public class MytypeEvaluator implements TypeEvaluator<Point> {


    @Override
    public Point evaluate(float fraction, Point startValue, Point endValue) {
        float dtX = endValue.getX()-startValue.getX();
        float dtY= endValue.getY() - startValue.getY();
        return new Point(fraction*dtX,fraction*dtY);
    }
}

自定义的估值器。

使用如下

    mgirl = (ImageView) findViewById(R.id.iv_girl);
    ValueAnimator valueAnimator = ValueAnimator.ofObject(new MytypeEvaluator(), new Point(0, 0), new Point(500, 500)).setDuration(2000);
    valueAnimator.setInterpolator(new MyInterpolator());
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Point animatedValue = (Point) animation.getAnimatedValue();
            mgirl.setTranslationX(animatedValue.getX());
            mgirl.setTranslationY(animatedValue.getY());
        }
    });
    valueAnimator.start();


就那么简单 插值器与估值器说到这你肯定明白了。

(三) 说说对任意属性做动画。

这里从一个需求说起,我们要对一个button 的宽度做动画,使它在2000毫秒 宽度增加500px 你肯定觉简单啊 ,把botton 在x 方向放大就不ok 了,你仔细看清,我们说的是宽度增加,如果x放大化button 内部的内容也放大了,效果很难看,如果恰巧button 在布局边上,你会反省button 直接跑出布局去了,这肯定不是我们要的效果啊,马上就会想到可以用objectAnimation操作button 的宽“with”啊,ObjectAnimator.ofInt(mButton,"with",0,500)

你可以试验一下,objectAnimator是没有效果的。如果你对任意属性不加判断直接做动画的话,轻的话梅没有效果,有些属性直接回造成crash的。

结论如下:如果你做动画的属性没有set方法的话,你去做动画,之间回crash  ,如果有set方法没用get方法的话  没有效果。

那怎么解决啊 官方给出了三种解决方法1 给对象加上set get方法,单是需要权限(这基本不可能实现啊) 2 用一个对象包裹 组建提供set get方法,3 使用ValueAnimator 自己操作view 的属性。

这里就说说第二种吧,各人感觉最简单的一种。代码

public class SwipButton {
    private Button button;

    public int getWith() {
        return button.getLayoutParams().width;
    }

    public void setWith(int with) {
        ViewGroup.LayoutParams layoutParams = button.getLayoutParams();
        layoutParams.width = with;
        button.setLayoutParams(layoutParams);
    }
}
包裹过程

ObjectAnimator with = ObjectAnimator.ofInt(mgirl, "with", 0, 500);
with.setDuration(2000);
with.start();

使用过程ok 解决了。你可能会问为什么呢?好吧下篇文章我们继续说吧。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值