Android群英传--动画机制与技巧(一)

动画是一个App的极为重要的部分,若把一个App看做是一个“人”,那么各种框架是组成这个“人”的各种骨骼,UI界面就是这个“人”的面部五官,肤色等外观,而动画就是“人体”内的各种软组织,用于缓冲,可以保护“人体”内“器官”不受“伤害”。若是缺少了动画,那么整个系统就会显得生硬而没有美感。

动画分类:

Android中的动画分为三类:最初的视图动画,然后加入了属性动画,然后又加入了矢量动画,一步一步的在不断完善。

视图动画:

介绍:

只是简单的改变View的视图位置,但是并不改变视图的点击事件的位置,也就是说若一个Button通过视图动画向右移动了一定的距离,但是其点击事件仍在原来的位置上,只适合用于做一下纯粹的动画效果,并不适合有用户交互的需求。

可以用的有平移动画,旋转动画,透明度动画,缩放动画这四种基础动画,以及组合动画(四种基础动画的组合)

用法:

可以直接在Java代码中进行动画的设置,也可以将动画写在XML文件中,使用的时候直接加载。

1. 在Java代码中使用动画:

public void alpha(View view){
        //透明度渐变视图动画
        AlphaAnimation alphaAnimation = new AlphaAnimation(1,0);
        alphaAnimation.setRepeatMode(Animation.REVERSE);
        alphaAnimation.setRepeatCount(Animation.INFINITE);
        alphaAnimation.setDuration(3000);
        imageView.startAnimation(alphaAnimation);
    }

    public void translate(View view){
        //平移动画
        TranslateAnimation translateAnimation = new TranslateAnimation(0F,100F,0F,200F);
        translateAnimation.setDuration(3000);
        imageView.startAnimation(translateAnimation);
    }

    public void rotate(View view){
        //旋转动画
        RotateAnimation rotateAnimation = new RotateAnimation(0,90);
        rotateAnimation.setDuration(3000);
        imageView.startAnimation(rotateAnimation);

    }

    public void scale(View view){
        //缩放动画
        ScaleAnimation scaleAnimation = new ScaleAnimation(1F,2F,1F,3F);
        scaleAnimation.setDuration(3000);
        imageView.startAnimation(scaleAnimation);
    }

    public void set(View view){
        //基础动画的集合动画
        AnimationSet animationSet = new AnimationSet(true);
        animationSet.setDuration(1000);

        ScaleAnimation scaleAnimation = new ScaleAnimation(0F,2F,0F,2F);
        scaleAnimation.setDuration(3000);
        animationSet.addAnimation(scaleAnimation);//添加动画


        AlphaAnimation alphaAnimation = new AlphaAnimation(1,0);
        alphaAnimation.setRepeatMode(Animation.REVERSE);
        alphaAnimation.setRepeatCount(Animation.INFINITE);
        alphaAnimation.setDuration(3000);
        animationSet.addAnimation(alphaAnimation);//添加动画

        RotateAnimation rotateAnimation = new RotateAnimation(0,180);
        rotateAnimation.setDuration(3000);
        animationSet.addAnimation(rotateAnimation);//添加动画

        imageView.startAnimation(animationSet);
    }

2. 在XML文件中定义动画,直接在Java代码中加载:

在anim文件夹中分别定义需要的视图动画,在xml文件中定义动画的属性。

view_anim_alpha.xml:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1.0"
    android:toAlpha="0.0"
    android:duration="5000"
/>

view_anim_rotate.xml:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="180"
    android:duration="3000"
/>

view_anim_scale.xml:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="1"
    android:toXScale="2"
    android:fromYScale="0"
    android:toYScale="2"
    android:duration="3000"
/>

view_anim_translate.xml:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="3000"
        android:fromXDelta="100"
        android:toXDelta="400"
        android:fromYDelta="100"
        android:toYDelta="300"
/>

view_anim_set.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000">

    <rotate
        android:duration="3000"
        android:fromDegrees="0"
        android:toDegrees="90" />
    <scale
        android:duration="3000"
        android:fromXScale="1"
        android:toXScale="2"
        android:fromYScale="1"
        android:toYScale="2"/>
</set>

在Java代码中直接使用AnimationUtils.loadAnimation()方法加载xml文件中定义的动画

public void alpha(View view){
        //透明度渐变视图动画
        Animation alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.view_anim_alpha);
        imageView.startAnimation(alphaAnimation);
    }

    public void translate(View view){
        //平移动画
        Animation translateAnimation =  AnimationUtils.loadAnimation(this, R.anim.view_anim_translate);
        translateAnimation.setDuration(3000);
        imageView.startAnimation(translateAnimation);
    }

    public void rotate(View view){
        //旋转动画
        Animation rotateAnimation =  AnimationUtils.loadAnimation(this, R.anim.view_anim_rotate);
        rotateAnimation.setDuration(3000);
        imageView.startAnimation(rotateAnimation);
    }

    public void scale(View view){
        //缩放动画
       Animation scaleAnimation =  AnimationUtils.loadAnimation(this, R.anim.view_anim_scale);
        imageView.startAnimation(scaleAnimation);
    }

    public void set(View view){
        //基础动画的集合动画
        Animation animationSet = AnimationUtils.loadAnimation(this, R.anim.view_anim_set);
        animationSet.setDuration(1000);

        imageView.startAnimation(animationSet);
    }

属性动画:

介绍:

属性动画弥补了视图动画不具有交互性的缺点,其改变的是视图真实的属性,这样使得控件和其响应事件都能同步的在一起。但是属性动画也有使用的条件,即要改变所要操控的View对象的属性值时,view对象必须要有相应get和set方法。

ObjectAnimator常用的属性:
  • translationX,translationY:用于控制view在X,Y轴上的平移的距离。

  • X,Y:用于控制view左上角距离屏幕坐标原点的位置。

  • rotation,rotationX,rotationY: rotation只是控制view在2D上进行旋转;rotationX,rotationY配合使用可以实现view在3D上的旋转。

  • scaleX,scaleY: 分别控制view在水平X上和竖直Y上的缩放

  • pivotX,pivotY:控制view进行缩放,旋转变换时的中心点,默认情况下就是该view的中心点。

使用:
  1. 若要操作的view有对应的get和set方法:

    • 则可以通过ObjectAnimator类进行直接操作
  2. 若是没有对应的get和set方法,则有两种解决方式:

    • 将需要的view进行自行包装,自己封装get和set方法

    • 使用ValueAnimator对view当前各种数值的监听,从而实现对数值的改变,实现动画效果。

1. 有对应的get和set方法,直接在Java代码中使用:

public void alpha(View view){
        //透明度渐变视图动画
        ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(imageView,"alpha",0F);
        alphaAnimation.setRepeatMode(ValueAnimator.REVERSE);
        alphaAnimation.setRepeatCount(ValueAnimator.INFINITE);
        alphaAnimation.setDuration(3000);
        alphaAnimation.start();
    }

    public void translate(View view){
        //平移动画
        ObjectAnimator translateAnimationX = ObjectAnimator.ofFloat(imageView,"translationX",300);
        ObjectAnimator translateAnimationY = ObjectAnimator.ofFloat(imageView,"translationY",300);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(2000);
        animatorSet.playTogether(translateAnimationX,translateAnimationY);
        animatorSet.start();
    }

    public void rotate(View view){
        //旋转动画
        //只是进行2D旋转
       ObjectAnimator rotateAnimation = ObjectAnimator.ofFloat(imageView,"rotationX",30);
        //配合使用实现3D旋转
       ObjectAnimator rotateAnimationX = ObjectAnimator.ofFloat(imageView,"rotationX",30);
       ObjectAnimator rotateAnimationY = ObjectAnimator.ofFloat(imageView,"rotationY",60);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(2000);
        animatorSet.playTogether(rotateAnimationX,rotateAnimationY);
        animatorSet.start();
    }

    public void scale(View view){
        //缩放动画
        ObjectAnimator scaleAnimationX = ObjectAnimator.ofFloat(imageView,"scaleX",0.5F);
        ObjectAnimator scaleAnimationY = ObjectAnimator.ofFloat(imageView,"scaleY",2F);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(3000);
        animatorSet.playTogether(scaleAnimationX, scaleAnimationY);
        animatorSet.start();
    }

    public void set(View view){
        //基础动画的集合动画
        //配合使用实现3D旋转
        ObjectAnimator rotateAnimationX = ObjectAnimator.ofFloat(imageView,"rotationX",30);
        ObjectAnimator rotateAnimationY = ObjectAnimator.ofFloat(imageView,"rotationY",60);
        //透明度渐变
        ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(imageView,"alpha",0F);
        alphaAnimation.setRepeatMode(ValueAnimator.REVERSE);
        alphaAnimation.setRepeatCount(ValueAnimator.INFINITE);
        alphaAnimation.setDuration(3000);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(3000);
        animatorSet.playTogether(rotateAnimationX, rotateAnimationY,alphaAnimation);
        animatorSet.start();
    }

2. 无对应的get和set方法,使用包装的view类:

/**
  * 包装的view类
  */
    private static class WarpperView{
        private View mView;

        public WarpperView(View mView) {
            this.mView = mView;
        }

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

        public int getHeight(){
            return mView.getLayoutParams().height;
        }
    }

使用时直接将要操作的view传给WrapperView,并在WrapperView中添加相对应的get和set方法,直接通过ObjectAnimator操作WrapperView的实例对象就可以。

WarpperView warpperView = new WarpperView(imageView);
    ObjectAnimator objectAnimator = ObjectAnimator.ofInt(warpperView, "width", 500);
    objectAnimator.start();

3. 无对应的get和set方法,使用ValueAnimator:

ValueAnimator其实并不是直接是得View产生动画效果,但是其可以为动画提供所需要的数值,类似于一个数值发生器,通过监听动画过程中数值的变化,为view设置当前的显示状态。

    public void anim(View view) {
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(100,0);
        valueAnimator.setTarget(imageViewe);
        valueAnimator.setDuration(1000).start();
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //在这里可以获取到valueAnimator产生的数值,并将其设置给对应的view,这个是将imageView沿Y轴向下移动
                float value = (float) animation.getAnimatedValue();
                imageViewe.setTranslationY(value);

            }
        });
    }
属性动画的组合:

和视图动画一样,我们也可以同时组合多种属性动画实现更将多彩的动画效果。

方式一:使用PropertyValuesHolder:
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 300f);
        PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("translationY", 500f);
        PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("alpha", 0.5f);

        ObjectAnimator.ofPropertyValuesHolder(pvh1, pvh2, pvh3).setDuration(1000).start();
方式二:使用AnimatorSet:
ObjectAnimator translateAnimationX = ObjectAnimator.ofFloat(imageView,"translationX",300);
        ObjectAnimator translateAnimationY = ObjectAnimator.ofFloat(imageView,"translationY",300);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(2000);
        animatorSet.playTogether(translateAnimationX,translateAnimationY);
        animatorSet.start();

可以创建多个动画,然后将其放入到AnimatorSet中去,AnimatorSet类提了多种方法来控制其中动画的播放,包括:

  • 一起播放:playTogether()
  • 顺序播放:playSequentially()
  • animSet.play().with()
  • animSet.play().before()
  • animSet.play().after()
方式三:利用属性动画的自动驱动特性:

通过ObjectAnimator的setStartDelay()来使得动画实现自动驱动。

alphaAnimation.setStartDelay();
在XML中定义属性动画:

同样和视图动画一样,属性动画也可以在XML文件中进行定义,使用的时候直接加载已经定义好的动画。用法和视图动画在xml中的用法类似。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值