3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中又引入了一个新的动画系统:property animation,这三种动画模式在SDK中被称为property animation,view animation,drawable animation。

可通过NineOldAndroids项目在3.0之前的系统中使用Property Animation。

            tween animation:

               补间动画:支持简单的缩放、平移、旋转、透明度基本的动画,它只是改变了View对象绘制的位置,注意这是“绘制”,而不是实际的位置。比如你让一个button变成它的两倍大小,但是它能接受你点击的区域还是原来的button区域,没有做任何改变。

而且有一定的局限性。比如:你希望View有一个颜色的切换动画;你希望可以使用3D旋转动画;你希望当动画停止时,View的位置就是当前的位置,这个补间动画无法做到,虽然有个setFillAfter(停留在动画的最后一帧)和setFillBefore(停留在动画的第一帧),

(如果你想使用这两个属性,需要将setFillEnabled设置为true),但是还是建议用 property animation去取代补间动画。

             具体到类是 AlphaAnimation ScaleAnimation RotateAnimation TranslateAnimation,都是继承的Animation这个类,还有个动画集合类 AnimationSet,可以通过addAnimation的方法将几个补间动画 一起执行,无法设置动画执行的顺序。其中关于ScaleAnimation

和RotateAnimation 有几个参数需要说明下,就是int pivotXType,float pivotX,int pivotYType, float pivotY,其中pivotX和pivotY确定了动画缩放或者旋转的中心点,pivotXType和pivotYType有Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF和Animation.RELATIVE_TO_PARENT

三种类型,Animation.ABSOLUTE:具体的坐标值,指绝对的屏幕像素单位;Animation.RELATIVE_TO_SELF:相对自己的坐标值,0.1f是指自己的坐标值乘以0.1;Animation.RELATIVE_TO_PARENT:相对父容器的坐标值,0.1f是指父容器的坐标值乘以0.1,我自己大多是

用Animation.RELATIVE_TO_SELF这种类型,比如当pivotXType和pivotYType都是Animation.RELATIVE_TO_SELF的时候,pivotX和pivotY都等于0.5时就表示动画从组件的中心点开始缩放或者旋转。

 

         property animation:

            属性动画:属性动画与 补间动画最大的区别就是它是真正的改变了view的属性,而且属性动画不止适用于view,还可以应用于任何对象,Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。

           具体类是ValueAnimator和ObjectAnimator这两个类,其中ObjectAnimator是继承ValueAnimator的。实际应用中一般都会用ObjectAnimator来产生某一对象的动画,但用ObjectAnimator有一定的限制,要求动画作用的对象提供该属性的get和set方法,目前用的比较多的是

alpha、scaleX、scaleY、rotation、rotationX、rotationY、translationX、translationY、X、Y和backgroundColor,这些属性基本能够满足一般的动画需求。使用示例如下:

           ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0.3f);第1个参数需要进行动画的view,第2个参数是需要改变的属性名,第3个参数其实是一个可变参数数组,比如这个例子就是view由当前的透明度变化到0.3f,如果是ObjectAnimator.ofFloat(view, "alpha", 0.3f,0.9f)

则表示view的透明度先直接变成0.3f,从0.3f才开始动画变到0.9f。之后再调用animator.start()方法即开始动画,这其中可以设置多个动画的相关参数,常用的有setDuration设置动画周期,addListener增加动画监听器,cancel()停止动画,end()结束动画,setRepeatCount()设置动画

重复的次数,如果为-1或者ObjectAnimator.INFINITE则表示一直循环进行动画,setRepeatMode()表示设置动画的模式,模式有ObjectAnimator.RESTART:重新执行动画  ObjectAnimator.REVERSE:反向执行动画。setStartDelay()设置动画执行的延时时间。

          同补间动画一样,属性动画里面同样有个动画集合类AnimatorSet用来多种动画同时执行,我认为比 补间动画的AnimationSet(注意两个不是一个类,一个是Animation ,一个是Animator)更好的地方就是AnimatorSet可以控制动画的执行顺序。

AnimatorSet.playSequentially()方法是顺序执行动画,AnimatorSet.playTogether()是同时执行动画。还有play().with/after/before的方法来控制动画的执行的顺序,但我用的时候感觉最好是作用于不同view的animator,如果是同一个view的animator感觉顺序是乱的。

         如果要同时对1个view进行多种动画的组合其实还有两种方法,第一种就是使用PropertyValuesHolder类。查看PropertyValuesHolder类的api可以发现其实PropertyValuesHolder的方法与ObjectAnimator很类似。PropertyValuesHolder可以作为ObjectAnimator.ofPropertyValuesHolder方法中

的一个可变参数,示例如下:

        PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofFloat("alpha", 0.3f);

        PropertyValuesHolder scaleHolder = PropertyValuesHolder.ofFloat("scaleX", 1.5f);

        PropertyValuesHolder rotationHolder = PropertyValuesHolder.oInt("rotation", 360);

        PropertyValuesHolder translationHolder = PropertyValuesHolder.ofInt("translationY", -100);

        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(btSet, alphaHolder, scaleHolder, rotationHolder, translationHolder);

        objectAnimator.start();

        第2种方法就是使用ViewPropertyAnimator类,ViewPropertyAnimator是API level 12 引进的,它是用来做针对View对象的多个属性动画功能,如果要同时变换一个View的多个属性的话,ViewPropertyAnimator提供了一种更方便和更适合的方法。

 而且由于多个属性的invalidate方法调用统一管理,而不是之前的分别调用,所以还会有一些性能优化。ViewPropertyAnimator的对象View.animate()直接获取,查看源码可以发现这其实是一个单例方法。

ViewPropertyAnimator实现上面的示例的动画则 view.animate().alpha(0.3f).scaleX(1.5f).rotation(360).translationY(-100).start(),更为简洁。

              其实ObjectAnimator里面还有两个比较重要的方法setInterpolator和setEvaluator。

              setInterpolator是设置动画的插值器,可以改变动画的动画绘制的速率,android里面有很多插值器,都是实现了Interpolator这个接口,里面只需要实现public float getInterpolation(float input)这个方法.

网上看到一个对interpolator解释很形象的说明:现在小明去买酱油,规定时间是1个小时到达,里程是1 公里;现在小明心里唯恐无法达到,所以先跑起来了,但因为体力消耗所以逐渐的慢下来了;然后成功到达。这样的一个过程中把小明逐渐慢下来的这个过程抽象出 来也就是 Interpolator  的工作;

当然 Interpolator 也可以控制小明先慢慢热身然后越跑越快最后达到。这个方法中 float input的参数的范围是0到1,当动画开始时为0,当动画结束时为1,我的理解就是一个与时间相关的系数,比如动画周期是1000毫秒,当动画执行到500毫秒时,这个方法出入的input就是0.5。

android官方提供了几种插值器,http://my.oschina.net/banxi/blog/135633 这篇文章介绍的很详细,每个插值器就是实现这个public float getInterpolation(float input)  方法中的算法不一样而已。

我使用的比较多的场景就是在改变焦点框的大小的时候 在这个方法里面不停的设置的焦点框的layoutparams。

@Override

    public float getInterpolation(float input) {

        if (focusView != null) {

            RelativeLayout.LayoutParams layoutParams = (LayoutParams) focusView.getLayoutParams();

            switch (focusSizeChange) {

            case 1:

                layoutParams.width = (int) (focusViewWidth - FOCUS_RATIO_WIDTH * input);//focusViewWidth是焦点框动画前的宽度,FOCUS_RATIO_WIDTH是焦点框变化前后的宽度的差值

                layoutParams.height = (int) (focusViewHight - FOCUS_RATIO_HEIGHT * input);//focusViewHight 是焦点框动画前的高度,FOCUS_RATIO_HEIGHT是焦点框变化前后的高度的差值

                break;

            case -1:

                layoutParams.width = (int) (focusViewWidth + FOCUS_RATIO_WIDTH * input);

                layoutParams.height = (int) (focusViewHight + FOCUS_RATIO_HEIGHT * input);

                break;

            default:

                break;

            }

            focusView.setLayoutParams(layoutParams);

        }

        return input;

    }

 

                     setEvaluator方法是设置view的属性计算器。android官方提供了3个evaluator,IntEvaluator:属性的值类型为int;FloatEvaluator:属性的值类型为float;ArgbEvaluator:属性的值类型为十六进制颜色值

ObjectAnimator中常用的用来设置view的背景,示例如下:

        ObjectAnimator colorAnim = ObjectAnimator.ofInt(btColor, "backgroundColor", CYAN, BLUE, RED);

        colorAnim.setEvaluator(new ArgbEvaluator());

        colorAnim.setRepeatCount(ValueAnimator.INFINITE);

        colorAnim.setRepeatMode(ValueAnimator.REVERSE);

        colorAnim.setDuration(3000);

        colorAnim.start();

 

                    上面这段代码的效果是view的背景会从青色逐渐变为蓝色再逐渐变为红色。其实setEvaluator方法用的比较多的是在ValueAnimator类中,ValueAnimator是需要指定属性,但是不需要操作的对象的属性一定要有getter和setter方法,

这里就是需要在setEvaluator方法中实现一个TypeEvaluator接口,属性对象由 valueAnimator.setObjectValues方法实现,ValueAnimator必须加入addUpdateListener监听器,在监听器里面不停的更新view的属性。

网上较多的一个实现图片抛物线动画的例子如下:

          ValueAnimator valueAnimator = new ValueAnimator();

         valueAnimator.setObjectValues(new PointF(0, 0));

         valueAnimator.setTarget(ivBoll);

         valueAnimator.setDuration(5000);

         valueAnimator.setEvaluator(new TypeEvaluator() {

 

            @Override

            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {//fraction 这个参数的值也是从0到1,我感觉与插值器里面的参数是一个意思,都是与时间相关的系数

                PointF p = new PointF();

                p.x = 1000 * fraction ;

                p.y = 590 * fraction *fraction;

                return p;

            }

        });

        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

 

            @Override

            public void onAnimationUpdate(ValueAnimator animation) {

                PointF p = (PointF) animation.getAnimatedValue();

                ivBoll.setX(p.x);

                ivBoll.setY(p.y);

            }

        });

        valueAnimator.start();

 

         到这里属性动画就介绍的差不多了,有了属性动画后,补间动画就基本很少使用了,但是还有一个地方还需要使用,就是布局动画里面,就是viewgroup里面添加view或者删除view时候的动画。使用比较多的场景就是在

adapterview、listview和gridview中。这里我们需要获取一个LayoutAnimationController对象,LayoutAnimationController可以控制子view进行动画的顺序,setOrder方法里面有3种类型:

LayoutAnimationController.ORDER_RANDOM-随机 ,LayoutAnimationController.ORDER_REVERSE-逆序  LayoutAnimationController.ORDER_NORMAL-顺序

示例如下:

private LayoutAnimationController getTopListAnim() {

       AnimationSet set = new AnimationSet(true);

        Animation animationAlpha = new AlphaAnimation(0.0f, 1.0f);

        animationAlpha.setDuration(470);

        set.addAnimation(animationAlpha);

        Animation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,

                -3.0f, Animation.RELATIVE_TO_SELF, 0.0f);

        animation.setDuration(470);

        set.addAnimation(animation);

        LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);//第1个参数是动画类,第2个参数是指上一个子view动画完成后,下一个子view进行动画的延时时间

        return controller;

listview或者gridview使用的时候    gridview.setLayoutAnimation(getTopListAnim()); adapter.notifyDataSetChanged();

当然除了上述的3种排序之外,如果需要更为复杂的显示子view的顺序,那我们就需要继承LayoutAnimationController类并实现protected int getTransformedIndex(AnimationParameters params)这个方法

示例如下:

class MyLayoutAnimationController extends LayoutAnimationController {

        public static final int ORDER_CUSTOM = 7;

       private int row;//gridview的行数

        public MyLayoutAnimationController(Animation animation, float delay) {

            super(animation, delay);

            // TODO Auto-generated constructor stub

        }

        public MyLayoutAnimationController(Animation animation) {

            super(animation);

            // TODO Auto-generated constructor stub

        }

        public MyLayoutAnimationController(Context context, AttributeSet attrs) {

            super(context, attrs);

            // TODO Auto-generated constructor stub

        }

        @Override

        protected int getTransformedIndex(AnimationParameters params) {

            if (getOrder() == ORDER_CUSTOM) {//这里我们实现自己的顺序算法,我实现的是1个gridview从左上延对角线往右下显示子view的算法

                return params.index / row + params.index % row;//params.index是指子view在viewgroup中的索引

            }

            return super.getTransformedIndex(params);

        }

    }

更多相关文章

  1. Android中TextVIew一些属性
  2. 从零开始学习android
  3. 详解 Android(安卓)的 Activity 组件
  4. TextView显示链接
  5. 详解 Android(安卓)的 Activity 组件
  6. Android(安卓)Activity界面切换添加动画特效
  7. EditText属性简介
  8. android 自定义控件属性
  9. Android中通过Intent 调用图片、视频、音频、录音、拍照

随机推荐

  1. JS 函数的执行时机
  2. 3.【商城后台管理系统】基于TP6开发登陆
  3. 2.【商城后台管理系统】基于TP6开发后台
  4. 函数的要素
  5. parcle打包工具的一些资料链接
  6. setInterval这个api
  7. PHP:【商城后台管理系统】部署管理员一级
  8. 微信抽奖小程序如何制作?
  9. 条件渲染v-if v-show、计算属性和监听器
  10. 一个返回数组最小数字的函数和一个能返回