Android动画--属性动画

在上一篇Android动画–视图动画中提到,Android视图动画有一个很大的弊端,即视图动画只是在视觉上将动画进行呈现,但是事件响应位置还是在动画之前的位置,例如我们将一个View使用位移动画改变位置,并使用animation.setFillAfter(true)保留结束时的状态,此时点击view所在的位置,不会进行响应,只有点击之前的位置才能响应事件。

Android的属性动画却可以很好的解决这个问题,因为属性动画是真实的改变view的属性,所以事件响应的区域也会发生改变。

属性动画中我们使用比较多的包括ObjectAnimator,ValueAnimator以及AnimatorSet:

1.ValueAnimator

调用ValueAnimator的ofFloat,ofInt,ofObject静态方法创建ValueAnimator对象;

            ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f,1f);
            valueAnimator.setDuration(2000);
            valueAnimator.start();

上边的例子实现了2000ms内,值从0-1的变化过程,如果我们需要对value的值的改变进行监听以实现我们自己的逻辑,则需要对ValueAnimator添加AnimatorUpdateListener监听器;

      valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                         Float value = animation.getAnimatedValue();
                         //to do something          
                    }
                });

同时我们也可以对其设置插值器等:

valueAnimator.setInterpolator(new LinearInterpolator());

2.ObjectAnimator

通过ObjectAnimator的静态工厂方法,我们可以很方便的创建ObjectAnimator对象,而且给我们提供了很多种方法以适应我们根据不同的需求进行创建,例如:

            ObjectAnimator.ofInt(Object target, String propertyName, int... values);
//只有API Level 21以上可根据path创建动画,其它相似
            ObjectAnimator ofInt(Object target, String xPropertyName, String yPropertyName,
            Path path);

以及其他ofFloat,ofArgb,ofObject等方法,此处不再一一赘述,我们可以根据名称很方便的选择我们需要的创建方法。此处我们以ofFloat方法为例:

                ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationX", 400200300);
                objectAnimator.setDuration(2000);
                objectAnimator.start();

第一个参数为我们需要设置属性动画的view,第二个参数为需要操纵的属性的名称,第三个参数为一个可变数组参数,如果我们只设置一个参数为400,即为从当前位置变化到400,如果设置为上边代码中400,200,300,即为从400->200->300,而不是 当前->400->200->300;同时我们也可以对属性动画设置时长,插值器等其他属性,与之前的视图动画相同。

在使用ObjectAnimator的时候,我们要操纵的属性必须有get和set方法,否则动画无效,因此在我们自定义的控件中,如果需要给某个自定义属性添加属性动画,则需要提前给该属性添加get和set方法。同时如果动画的对象是view,为了能够显示动画效果,可能还需要在动画的onAnimationUpdate中调用view.invalidate()方法来刷新屏幕的显示,例如对Drawable对象的color属性设置动画。但View定义的setter方法,例如setAlpht()和setTranslationX()等方法都会自动调用invalidate()方法,因此不需要我们额外的进行调用。

                objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                       view.invalidate(); 
                    }
                });

3.动画事件的监听

如果需要监听Animator的动画开始事件,结束时间,动画重复事件,动画值改变事件,并根据事件提供相应的处理代码,则应该为Animator对象设置事件监听器;

                objectAnimator.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) {

                    }
                });

某些时候,我们可能只对某些事件感兴趣,我们可以通过AnimatorListenerAdapter来选择我们需要的事件进行监听:

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

4.AnimatorSet和PropertyValuesHolder

我们可以通过PropertyValuesHolder来对view的多个属性设置动画,类似于视图动画的AnimatorSet,以此来实现多属性动画的共同作用:

                PropertyValuesHolder ph1 = PropertyValuesHolder.ofFloat("translationX",300f);
                PropertyValuesHolder ph2 = PropertyValuesHolder.ofFloat("scaleX",1f,0.5f);
                PropertyValuesHolder ph3 = PropertyValuesHolder.ofFloat("scaleY",1f,0.5f);
                ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, ph1, ph2, ph3);
                objectAnimator.setDuration(2000);
                objectAnimator.start();

同样的我们也可以使用AnimatorSet来实现相同的效果,且能够实现更为精确的效果,例如通过playTogether(),playSequentially(),或者animSet.play().with()、before()、after()设置多个动画的协同工作方式,从而实现对动画做到更为精准的控制;

5.通过XML设置属性动画

我们一般讲视图动画的xml定义在anim文件夹,而将objectAnimator放置在animator文件夹下:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:propertyName="scaleX"
    android:valueFrom="1.0"
    android:valueTo="2.0"
    android:valueType="floatType">

</objectAnimator>

我们可以在xml文件中很方便的设置我们需要的参数;
在程序中的调用可以通过如下方法进行调用:

AnimatorInflater.loadAnimator(context, R.animator.myanim);

此方法可以调用animator文件夹下的动画,而通过之前视图动画中AnimationUtils.loadAnimation()只能调用anim文件夹下的动画,不能调用animator文件夹下的动画。

然后通过animtor.setTarget(view)的方法为某一view设置该动画,然后调用animator.start()开启动画。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值