android属性动画

属性动画中最基础的 ObjectAnimator

ObjectAnimator 是属性动画中最重要的实行类,创建一个ObjectAnimator只需要通过他的静态工厂方类直接返回一个ObjectAnimator对象。参数包括一个对象和对象的属性名字,但这个属性必须有getset函数,内部会通过反射机制来调用set函数修改对象属性值,也可以调用setInterpolator设置对应的差值器。

属性动画操作的是属性,所以被操作的view可以响应事件。

例子:实现平移动画

ObjectAnimator animator = ObjectAnimator.ofFloat(
                view,
                "translationX",
                300
        );
animator.setDuration(300);
animator.start();
  • 第一个参数是要操纵的View
  • 第二个参数是要操作的属性
  • 第三个是一个可变数组参数,需要穿进去该属性变化的一个取值过程,这里就是变化到300
  • 下面是给动画设置时长,差值器等属性

注意到ofFloat方法,这是源码中的注释

/**
 * Constructs and returns an ObjectAnimator that animates between float values. A single
 * value implies that that value is the one being animated to. Two values imply starting
 * and ending values. More than two values imply a starting value, values to animate through
 * along the way, and an ending value (these values will be distributed evenly across
 * the duration of the animation).
 *
 * @param target The object whose property is to be animated. This object should
 * have a public method on it called <code>setName()</code>, where <code>name</code> is
 * the value of the <code>propertyName</code> parameter.
 * @param propertyName The name of the property being animated.
 * @param values A set of values that the animation will animate between over time.
 * @return An ObjectAnimator object that is set up to animate between the given values.
 */

大概意思是:

/**
 * 构造并返回一个浮点值之间的动画ObjectAnimator。单
 * 值意味着该值被动画的之一。两个值意味着启动
 * 和结束值。多于两个值意味着一个起始值,值动画通过
 * 一路走来,和结束值(这些值将均匀分布在整个
 * 动画的持续时间)。
 *
 * @参数target其属性是动画的对象。这个对象应该
 * 有它的公共方法叫做<代码>的setName()</代码>,其中<代码>名称</ code>的是
 * 在<code>的值propertyname</ code>的参数。
 * @参数PROPERTYNAME被动画的属性的名称。
 * @参数值一组动画将随着时间的推移之间的动画值。
 * 返回:已设置给定的值之间设置动画的ObjectAnimator对象。
 */

在使用ObjectAnimator的时候要注意的就是属性必须有getset方法,否则ObjectAnimator就无法生效。下面是常用的可以直接使用属性动画的属性值:

  • translationXtranslationY:这两个属性作为一种增量来控制着View对象从它布局容器左上角坐标偏移的位置。
  • rotation,rotationX,rotationY:这三个属性控制View对象围绕支点进行2D和3D旋转。
  • scaleX,scaleY:这两个属性控制View对象围绕它的支点进行2D缩放。
  • pivotX,pivotY:这两个属性控制着View对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,支点是View对象的中心点。
  • xy:这是两个简单实用的属性,它描述了View对象在它容器中的最终位置,它是最初左上角坐标和translationX、translationY值的累计和。
  • alpha:它表示View对象的alpha透明度。默认是1(不透明),0代表完全透明(不可见)

如果一个属性没有有getset方法,有两种解决方法。

  1. 通过自定义一个属性类或包装类来间接给这个属性添加get、set方法。
  2. 通过ValueAnimator实现

第一种,通过自定义一个属性类或包装类来间接给这个属性添加get、set方法:

WrapperView wrapper = new WrapperView(view);
ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();


private static class WrapperView {
    private View mTarget;

    public WrapperView(View mTarget) {
        this.mTarget = mTarget;
    }

    public int getWidth() {
        return mTarget.getLayoutParams().width;
    }

    public void setWidth(int width) {
        mTarget.getLayoutParams().width = width;
        mTarget.requestLayout();
    }
}

PropertyValuesHolder

如果针对同一个对象的多个属性,要同时作用多种动画,可以使用PropertyValuesHolder来实现,比如在平移中,同时改变X、Y轴的缩放,可以这样实现:

PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 300f);
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2, pvh3).setDuration(1000).start();

ValueAnimator

ValueAnimator本身不提供任何动画效果,它更像一个数值发生器,用来产生具有一定规律的数字。从而让调用者控制动画的实现过程,ValueAnimator的一般使用方法如下:

ValueAnimator animator = ValueAnimator.ofFloat(0, 100);
animator.setTarget(view);
animator.setDuration(5000).start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Float value = (Float) animation.getAnimatedValue();
        //TODO use the value
        Log.i("MainActivity", "value = " + value);
    }
});

其中AnimatorUpdateListener监听数值的变换,从而完成动画的变换,这个例子中,value输出的是从0到100

动画事件监听

一个完整的动画监听包括四个过程:

ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
anim.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
        
    }

    @Override
    public void onAnimationEnd(Animator animation) {

    }

    @Override
    public void onAnimationCancel(Animator animation) {

    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }
});

但是大部分时候,我们只关心onAnimationEnd事件,所以还可以这样通过AnimatorListenerAdapter选择想要的事件进行监听:

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

AnimatorSet

对于一个属性同时作用多个属性动画效果,除了使用PropertyValuesHolder外,还可以使用AnimatorSet,而且AnimatorSet还可以实现更为精确的顺序控制。

ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", 300f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0, 1f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0, 1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1, animator2, animator3);
set.start();

在属性动画中,AnimatorSet通过playTogether();playSequentially();set.play().with();set.play().before();set.play().after();这些方法来控制多个动画的协同工作方式,从而做到对动画播放顺序的精确控制。

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

推荐阅读更多精彩内容