美文网首页Android开发Android知识移动开发
浅析Android动画(二)——Property Anim属性动

浅析Android动画(二)——Property Anim属性动

作者: JC_Hou | 来源:发表于2016-08-19 11:06 被阅读223次

    属性动画从字面上看就是对于属性的变换,它与变换动画最大的区别就是属性动画注重与用户的交互
    举个例子:在变换动画中,将一个imageView设置点击事件,将其从左往右移动100dp,点击现有位置的imageView,并不会有点击事件,点击原有的位置将触发点击事件;而属性变化中,imageView的真实位置跟随着动画的移动而移动
    变换动画请走链接浅析Android动画(一)——Tween Anim

    相似的,属性动画拥有和变换动画相同的一些动画,alpha,translate,rotate,scale……但却比变化动画又更加精细,归根结底它变换的是属性,所有View对象拥有的属性都可以被操作。

    属性动画也可以在布局文件中声明和在代码中声明,但从我个人角度来看,更喜欢在代码使用的形式,在这里只贴代码,有兴趣的可以自己去研究一下xml中的使用。

    基本使用:

    ObjectAnimator.ofFloat(Object 0,String propertyName,float...values);
    ObjectAnimator.ofInt(Object 0,String propertyName,int...values);
    

    /**

    • 第一个参数,要操作的对象
    • 第二个参数,要操作的对象属性,对象拥有的get,set属性都可以操作,相同的属性有相同的起始点
    • 第三个参数,float... values,变化的值,可以是一个,可以是多个 ,如果只有一个值,表示声明终止状态,并且无法多次触发动画效果,多个值可以多次触发效果
      */
      共有方法:
      setDuration(long duration);//设置时间
      setStartDelay();//设置动画延迟播放的时间
      setRepeatMode(int type);//设置重复模式,reverse反序,restart正序
      setRepeatCount(int value);//设置重复次数,特殊的:-1为一直重复
      addListener(AnimatorListener listener);//为动画设置监听事件,监听动画的开始、结束、取消、重复、暂停、恢复
      setInterpolator(Interpolator interpolator);//设置插值器
    Translate

    属性:"translationX","translationY","X","Y",区别在于前二者是相对对象自身的左上角,后二者是相对于屏幕的左上角

    //从现有位置移动到相对于 屏幕 左上角的位置,不可以重复,因为终点位置相同,多次触发不会重复效果,横坐标与原始位置一致
    ObjectAnimator.ofFloat(mImageView,"Y",100f).setDuration(1000).start();```
    
    

    //从相对于 屏幕 左上角的指定位置移动到相对于 屏幕 左上角的另一个位置,可以重复触发效果,因为有起点终点,横坐标与现有原始一致
    ObjectAnimator.ofFloat(mImageView,"Y",0f,100f).setDuration(1000).start();```

    //从相对于 自身 左上角的指定位置移动到相对于 自身 左上角的另一个位置,可以重复触发效果,因为有起点终点,横坐标与原始位置一致
    ObjectAnimator.ofFloat(mImageView,"translationY",0f,100f).setDuration(1000).start();```
    
    

    //从现有位置移动到相对于 自身 左上角的坐标,多次触发不会重复效果,横坐标与原始位置一致
    ObjectAnimator.ofFloat(mImageView,"translationY",100f).setDuration(1000).start();```
    类似的还有X方向的变化

    Rotate

    属性:"rotation","rotationX","rotationY"
    "rotation"与变换动画中的一致,可以声明起止点,终点大的顺时针,否则逆时针,只声明一个终点,则旋转到相对于最原始的旋转角度
    "rotationX"和"rotationY"是3维的动画效果:"rotationX"表示绕与X轴同方向的中线旋转(上下翻转),"rotationY"表示绕与Y轴同方向的中线旋转(左右翻转)

    //旋转到相对于原始角度的值,不可以重复 
    ObjectAnimator.ofFloat(mImageView,"rotation",360f).setDuration(1000).start();```
    
    

    //可以重复
    ObjectAnimator.ofFloat(mImageView,"rotation",0f,180f).setDuration(1000).start();```

    //绕x轴方向的中线旋转
    ObjectAnimator.ofFloat(mImageView,"rotationX",0f,180f).setDuration(1000).start(); ```
    
    

    //绕y轴方向的中线旋转
    ObjectAnimator.ofFloat(mImageView,"rotationY",0f,360f).setDuration(1000).start();```

    Scale

    属性:"scaleX","scaleY"

    ObjectAnimator.ofFloat(mImageView,"scaleX",0f).setDuration(1000).start();//不可多次触发
    ObjectAnimator.ofFloat(mImageView,"scaleX",1f,0f).setDuration(1000).start();```
    这个很好理解
    
    #####Alpha
    > 属性:"alpha"
    
    `ObjectAnimator.ofFloat(mImageView,"alpha",0f).setDuration(1000).start();//不可多次触发`
    `ObjectAnimator.ofFloat(mImageView,"alpha",1f,0f).setDuration(1000).start();`
    这个也很好理解
    
    ###组合动画:
    - 最简单的 :
    这两个方法就已经可以进行同时进行组合动画了
    

    ObjectAnimator.ofFloat(mImageView,"scaleX",0f).setDuration(1000).start();
    ObjectAnimator.ofFloat(mImageView,"scaleY",0f).setDuration(1000).start();```

    • 更好的办法:
      系统提供了更好的办法:PropertyValuesHolder,字面上就可以看到它是属性值的保存容器
      我们将动画先从PropertyValuesHolder使用:
    PropertyValuesHolder p1=PropertyValuesHolder.ofFloat("scaleX",1f,0f);
    PropertyValuesHolder p2=PropertyValuesHolder.ofFloat("scaleY",1f,0f);`
    随后再调用
    ObjectAnimator.ofPropertyValuesHolder(Object o,PropertyValuesHolder...values)方法
    这个方法第一个参数是操作对象,第二个参数就是PropertyValuesHolder数组了;
    `objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mImageView, p1, p2);
    objectAnimator.setDuration(1000);
    objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
    objectAnimator.setRepeatCount(-1);
    objectAnimator.start();```
    
    - 更更更好的办法:
    类似于变换动画的AnimationSet动画集合,属性动画有它专门的集合:AnimatorSet,并且可以更加丰富的操作动画
    
    先创建3个Animator:
    

    ObjectAnimator animator1 = ObjectAnimator.ofFloat(mImageView, "alpha", 1f, 0.2f);
    ObjectAnimator animator2 = ObjectAnimator.ofFloat(mImageView, "rotationX", 0f, 360f);
    ObjectAnimator animator3 = ObjectAnimator.ofFloat(mImageView, "rotationY", 0f, 360f);再创建AnimatorSetA:AnimatorSet set=new AnimatorSet();```

    接下来神奇的事情将会发生:

    set.playTogether(animator1,animator2,animator3);//同时进行动画
    set.playSequentially(animator2,animator1,animator3);//按顺序播放
    set.play(animator1).with(animator2);//两个动画一起进行
    set.play(animator3).after(1000);//延迟1秒
    set.play(animator3).after(animator1);//3在前2个动画之后
    set.play(animator3).before(animator1);//3在前2个动画之前
    

    发现只要非常简单的代码就可以实现很丰富的动画操作

    监听事件

    animator和animatorSet都有此监听事件

    set.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
        }
        @Override
        public void onAnimationEnd(Animator animation) {
            Toast.makeText(AnimActivity.this,"anim end",Toast.LENGTH_SHORT).show();
        }
        @Override
        public void onAnimationCancel(Animator animation) {
        }
        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    });```
    
    这个AnimatorListener()是系统已经设置好的,但是有一点不好,四个方法都要实现,而且缺少了暂停和恢复的监听
    幸好系统有另一个方法
    

    set.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationCancel(Animator animation) {
    super.onAnimationCancel(animation);
    }
    @Override
    public void onAnimationEnd(Animator animation) {
    Toast.makeText(AnimActivity.this,"anim end",Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onAnimationPause(Animator animation) {
    Toast.makeText(AnimActivity.this,"anim pause",Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onAnimationResume(Animator animation) {
    Log.d("jc","resume");
    Toast.makeText(AnimActivity.this,"anim resume",Toast.LENGTH_SHORT).show();
    }
    });```
    在这个匿名内部类里面可以选择性的重写这六个方法。

    ValueAnimator:

    ObjectAnimator也是继承了ValueAnimator这个类
    属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。

    ValueAnimator mAnimator;
    mAnimator=ValueAnimator.ofFloat(1,2);
    //设置监听
    mAnimator.setDuration(1000);mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float translate= (float) animation.getAnimatedValue();
            Log.d("jc”,"translate"+translate);
        }
    });
    //无限循环
    mAnimator.setRepeatCount(-1);
    mAnimator.setRepeatMode(ValueAnimator.REVERSE);
    mAnimator.start();```
    
    

    D/jc: translate1.0
    D/jc: translate1.0007129
    D/jc: translate1.0026846
    D/jc: translate1.0061558
    ...
    D/jc: translate1.9709702
    D/jc: translate1.9792609
    D/jc: translate1.986185
    D/jc: translate1.9917226
    D/jc: translate1.995858
    D/jc: translate1.9984586
    D/jc: translate1.9998422
    D/jc: translate1.9998002
    D/jc: translate1.998333
    D/jc: translate1.9954448
    D/jc: translate1.9914355
    D/jc: translate1.9858159
    D/jc: translate1.9788108
    D/jc: translate1.9704404
    ...
    D/jc: translate1.0328355
    D/jc: translate1.0239887
    D/jc: translate1.0169019
    D/jc: translate1.0107095
    D/jc: translate1.0059125
    D/jc: translate1.0025245
    D/jc: translate1.000555
    D/jc: translate1.0000099```

    可以看到结果在不断变换

    相关文章

      网友评论

        本文标题:浅析Android动画(二)——Property Anim属性动

        本文链接:https://www.haomeiwen.com/subject/ooyvsttx.html