属性动画(上)

来源:互联网 发布:阿里云备案幕布电子版 编辑:程序博客网 时间:2024/06/09 06:54


属性动画概述:

我理解的属性动画顾名思义就是改变对象的属性值,来达到动画效果。这期间在不停的处理这个属性值,当这个值不在被处理的时候也就是动画结束的时候。
可以理解为按照某种规律不停刷新属性值的过程。 而这个规律就是插值器。整个过程用数据来抽象的就是valueanimator。objectanimator是valueanimator的子类。
其已经实现了平移,渐变,旋转等动画效果。

通过ObjectAnimator可以操作任何对象,只要这个对象的属性有get和set方法,那么就可以用属性框架来操作这个属性。
如果这个对象呢没有提供get和set方法,或者get和set方法对某个属性的操作不一致,这时我们可以自己来提供get和set方法。或者用一个包装来
重新提供get和set方法。例如:
private  class ViewWrapper {  
    //所要操作的对象
    private View mTarget;  
  
    public ViewWrapper(View target) {  
        mTarget = target;  
    }  
     
    public int getWidth() {  
//例如要操作width属性
        return mTarget.getLayoutParams().width;  
    }  
  
    public void setWidth(int width) {  
//例如要操作width属性,这里根据业务需要操作width属性。
        mTarget.getLayoutParams().width = width;  
        mTarget.requestLayout();  
    }  


//还可以提供其他属性,根据业务需要即可。
}  

总之呢 ,才用属性动画时,要操作的对象的属性需要提供get和set方法。如果在开发中遇到一个

对象的属性有get和set方法,但是没有达到预期效果,这时,我们要认真查看get和set方法是不是

对属性有明确的定义和操作。有时需要仔细来看源码确定,遇到具体的需求在说。


常见的控件的属性有:

translationX/translationY :偏移距离属性
rotation,rotationX、rotaitionY:旋转,水平方向和数值方向旋转
scaleX、scaleY:X方面缩放动画,y方向缩放动画
X/Y:  对象的x,y坐标属性
alpha: 透明度属性


常用类:

ValueAnimator:

ObjectAnimator extent ValueAnimator:用来操作对象属性,常用的类。

利用属性动画实现一个移动效果:ObjectAnimator.ofFloat("操作对象","当前动画属性","当前动画属性参数","当前动画属性参数");//X方向上平移150像素  :相对位置为当前坐标ObjectAnimator.ofFloat(textView,"TranlationX",0f,150f).setduration(1000).start();//Y方向上平移150像素ObjectAnimator.ofFloat(textView,"TranlationY",0f,150f).setduration(1000).start();//相对位置为0,0原点ObjectAnimator.ofFloat(textView,"x",0f,150f).setduration(1000).start();ObjectAnimator.ofFloat(textView,"y",0f,150f).setduration(1000).start();

AnimatorUpdateListenter:属性动画的监听器,动画的每一帧更新时会调用此监听。

AnimatorListenerAdapter、AnimatorListener: 动画的监听事件,包括动画结束,开始,重新开始等等。通常用AnimatorListenerAdapter方便写。

动画的事件监听: ObjectAnimator translationX = ObjectAnimator.ofFloat(btn, "translationX",0f,200f);        ObjectAnimator translationY = ObjectAnimator.ofFloat(btn, "translationY",0f,200f);        ObjectAnimator rotation  = ObjectAnimator.ofFloat(btn, "rotation",0f,360f);              translationY.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {            }            @Override            public void onAnimationEnd(Animator animation) {                Toast.makeText(MainActivity.this,"平移动画结束了",Toast.LENGTH_SHORT).show();            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });//通常情况下,我们可以根据自己的业务需要来通过AnimatorListenerAdapter 实现监听,这么写显然更省力,代码也更少.  rotation.addListener(new AnimatorListenerAdapter() {            @Override            public void onAnimationEnd(Animator animation) {                super.onAnimationEnd(animation);                Toast.makeText(MainActivity.this,"旋转动画结束了",Toast.LENGTH_SHORT).show();            }        });//当然了如果想移除监听也可以        translationY.removeListener();        translationY.removeAllListeners();

//用来控制一组动画集合的执行

PropertyValuesHolder: 
AnimatorSet: 

执行一组动画:用 PropertyValuesHolder  ObjectAnimator.ofPropertyValuesHolder //属性动画如果不加控制的话执行起来是同时执行的。  PropertyValuesHolder rotation =  PropertyValuesHolder.ofFloat("rotation",0f,360f);//旋转360°        PropertyValuesHolder translationX =  PropertyValuesHolder.ofFloat("translationX",0f,200f);//x平移200个像素单位        PropertyValuesHolder translationY =  PropertyValuesHolder.ofFloat("translationY",0f,200f);//y平移200个像素单位        ObjectAnimator.ofPropertyValuesHolder(btn,translationX,rotation,translationY).setDuration(2000).start();//执行一组动画:AnimatorSet ObjectAnimator translationX = ObjectAnimator.ofFloat(btn, "translationX",0f,200f);        ObjectAnimator translationY = ObjectAnimator.ofFloat(btn, "translationY",0f,200f);        ObjectAnimator rotation  = ObjectAnimator.ofFloat(btn, "rotation",0f,360f); AnimatorSet set = new AnimatorSet();//        set.playTogether(rotation,translationX,translationY);//同时执行动画。异步的//        set.playSequentially(rotation,translationX,translationY); //按照顺序依次执行动画,而不是同步执行。        //可以调整动画的执行顺序,animatorSet.play(a1).before ,after,with ,//我们可以根据自己的业务需要来通过这几个方法组合        set.play(translationX).with(translationY).before(rotation);//先让平移动画执行,再让旋转动画执行。        set.setDuration(1000).start();

TypeEvaluators: 估值计算器 

自定义 估值器例子 :

  /**     * 抛物线     * @param view     */    public void paowuxian(final View view)    {        ValueAnimator valueAnimator = new ValueAnimator();        valueAnimator.setDuration(3000);        valueAnimator.setObjectValues(new PointF(0, 0));        valueAnimator.setInterpolator(new LinearInterpolator()); //思考这里的不同。。。//        valueAnimator.setInterpolator(new BounceInterpolator());        valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {            // fraction = t / duration,t是从0到3000的变化数字,因此fraction就是整个运行时长的一部分,并且是不断随着时间增长的一部分.            //可以将fraction理解为运行时长的时间的百分比,它的范围是0-1            int xcount = 0;            @Override            public PointF evaluate(float fraction, PointF startValue,                                   PointF endValue) {                Log.e("动画运行时长(ms):", fraction * 3000 + "--");                Log.e("动画运行fraction:", fraction + "--");                // x方向200px/s ,则y方向0.5 * 10 * t                PointF point = new PointF();                //抛物线核心计算                point.x = 200 * fraction * 3;                point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);//                //圆周运动:首先要分解圆周运动,X方向上是匀速运动                return point;            }        });        valueAnimator.start();        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                PointF point = (PointF) animation.getAnimatedValue();                //mBlueBall.setX(point.x);                // mBlueBall.setY(point.y);                view.setX(point.x);                view.setY(point.y);                Log.i("AS:", point.x + "-" + point.y);            }        });    }

Interpolators:什么是插值器:

用来定义动画的运动轨迹。比如translationX,在x轴方向的动画,加入从0移动到200,那么这个中间怎么移动呢,是直接平移还是曲线运动,
这里就会用到插值器。


参考资料::
插值器介绍:

http://blog.csdn.net/singwhatiwanna/article/details/17639987
http://blog.csdn.net/singwhatiwanna/article/details/17841165
http://blog.csdn.net/lmj623565791/article/details/38067475
慕课网属性动画教程:

http://www.imooc.com/video/5450


0 0