欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 动画使用解析

程序员文章站 2024-03-26 11:37:41
...

Android 动画不详解(主要介绍了使用方法)

Android 中的动画主要分为三类:补间动画,帧动画,和属性动画。
补间动画的效果比较少,也没有改变View的真实位置,只是改了视图显示的位置,位置移动之后点击事件仍发生在原来的位置。
帧动画类似于放电影,一帧一帧的播放就产生了动的效果。
属性动画是3.0之后加入的,3.0之前的设备无法使用属性动画,也可以使用网上的第三方库来兼容3.0以前的设备(第三方库内部做了转换,对3.0以前的设备仍使用补间动画,所以补间动画的缺点仍然存在)。

补间动画

补间动画(View动画)包括四种动画:

  • 平移动画 TranslateAnimation <translate>
  • 缩放动画 ScaleAnimation <scale>
  • 旋转动画 RotateAnimation <rotate>
  • 透明度动画 AlphaAnimation <alpha>

平移、旋转、和缩放都会涉及初始结束位置或者动画的中心点参数的配置,配置有两种形式:

  • 使用数字:代表移动的像素数;
  • 使用百分比:系统自己根据View的宽高进行换算

参数或者方法说明

  • fromXDelta、fromYDelta、toXDelta、toYDelta : 动画起始位置相对于默认状态的距离。单位是像素或者百分比
  • fromDegrees、toDegrees : 旋转和结束位置相对于默认状态的转动角度
  • pivotX、pivotY : 旋转和缩放的中心点。单位是相对于左上角的像素数或者百分比
  • fromXScale、toXScale、fromYScale、toYScale :缩放的倍率,0.5是原图的一半大小
  • duration : 动画的持续时间。单位是毫秒数
  • fillAfter:动画结束之后,是否停留在结束位置。true/false
  • interpolator : 差值器。默认的有线性,加速,减速三种,可自定义(自定义差值器最后在聊吧)。
  • repeatMode : 重复的模式,有重新开始和反转两种模式。Animation.REVERSE和Animation.RESTART
  • animation.setRepeatCount(100) : 设置重复的次数设置给AnmationSet没效果,要设置给Animation才有用

以xml形式来定义和使用动画

<!--设置一个动画集合-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fillAfter="true">
    <translate
        android:fromXDelta="-100%"
        android:fromYDelta="0"
        android:toXDelta="0%"
        android:toYDelta="100" />
    <rotate
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
    <scale
        android:fromXScale="0"
        android:fromYScale="0"
        android:pivotX="0"
        android:pivotY="0"
        android:toXScale="1"
        android:toYScale="1" />
    <alpha
        android:fromAlpha="0.5"
        android:toAlpha="1" />
</set>
<!--设置一个单独的动画-->
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">
</rotate>

下面是在Java代码中使用

Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim_translate);
animation.setRepeatCount(3);
imageView.startAnimation(animation);

以Java代码定义和使用补间动画

TranslateAnimation animation = new TranslateAnimation(
           Animation.RELATIVE_TO_SELF,-1,
           Animation.RELATIVE_TO_SELF,1,
           Animation.ABSOLUTE,-100,
           Animation.ABSOLUTE,100);
animation.setDuration(1000);
animation.setFillAfter(true);
animation.setInterpolator(new AccelerateInterpolator());
animation.setRepeatCount(-1);
animation.setRepeatMode(Animation.REVERSE);
imageView.startAnimation(animation);

//这段代码定义了一个在X方向和Y方向上不停做加速运动和减速往复运动的动画
//Animation.RELATIVE_TO_SELF就相当于xml中用百分数表示那种。感兴趣自己去看源码吧

帧动画

所有的动画方式本质都是一样的,隔一段时间改变一下视图的内容或者位置,连续的变动就会产生动画的效果。帧动画也一样,只是把视图的改变全部交给提前设计好的图片,由图片的切换产生动画效果。

使用:
xml中定义一个animation list

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/animation1" android:duration="200"/>
    <item android:drawable="@mipmap/animation2" android:duration="200"/>
    <item android:drawable="@mipmap/animation3" android:duration="200"/>
    <item android:drawable="@mipmap/animation4" android:duration="200"/>
    <item android:drawable="@mipmap/animation5" android:duration="200"/>
    <item android:drawable="@mipmap/animation6" android:duration="200"/>
</animation-list>

在Activity中直接使用就可以了

imageView.setImageResource(R.drawable.anim_airplane);
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();
animationDrawable.start();

属性动画

属性动画是Android API 11加入的动画形式,在补间动画中,只能进行平移、旋转、缩放、透明度的变化以及前面四种形式的组合而产生动画效果,效果是相对比较少的,一些复杂的动画效果实现起来就很很麻烦(如实现一个小球的曲线运动)。
属性动画可以对一个对象的任意属性值进行动画操作,只要这个属性有set方法。

涉及到的类:

  • Animator:属性动画的基类,提供了启动、暂停、重启、终止、以及设置差值器、设置动画时间、添加动画监听器等一系列功能。
  • ValueAnimator:继承自Animator,对任意的值进行动画,为动画提供了一个时间引擎,通过时间引擎来判断当前动画的进度,属性当前的值,以及设置属性值给对象。
  • ObjectAnimator:继承自ValueAnimator,可以对target对象的某一个属性值mProperty进行动画操作,通过直接改变对象的属性值可以很简单的对一个视图进行动画。
  • AnimatorSet:继承自Animator,可以设置按顺序或者同时播放一组动画。

ValueAnimator的使用

ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            //当前值
            int currentValue = (int) animation.getAnimatedValue();
            //当前进度
            float fraction = animation.getAnimatedFraction();

            Log.e("==","currentValue:"+currentValue+"\nfraction:"+fraction);
        }
    });
valueAnimator.start();

ObjectAnimator的使用:

ValueAnimator rotateAnim = ObjectAnimator.ofFloat(imageView,"rotation", 0, 360);
rotateAnim.setRepeatCount(5);
rotateAnim.setRepeatMode(ValueAnimator.REVERSE);

ValueAnimator scaleXAnim = ObjectAnimator.ofFloat(imageView,"scaleX", 1f, 0.5f, 1f);
scaleXAnim.setRepeatCount(5);
scaleXAnim.setRepeatMode(ValueAnimator.REVERSE);

ValueAnimator scaleYAnim = ObjectAnimator.ofFloat(imageView,"scaleY", 1f, 0.5f, 1f);
scaleYAnim.setRepeatCount(5);
scaleYAnim.setRepeatMode(ValueAnimator.REVERSE);

ValueAnimator alphaAnim = ObjectAnimator.ofFloat(imageView,"alpha", 1f, 0.5f, 1f);
alphaAnim.setRepeatCount(5);
alphaAnim.setRepeatMode(ValueAnimator.REVERSE);

AnimatorSet set = new AnimatorSet();
set.playTogether(colorAnim, transYAnim, alphaAnim);
set.setDuration(100);
set.setInterpolator(new LinearInterpolator());
set.start();

自定义差值器和估值器

ValueAnimator transYAnim = ObjectAnimator.ofFloat(imageView,
                        "translationY", 0, 200);
transYAnim.setRepeatCount(5);
transYAnim.setRepeatMode(ValueAnimator.REVERSE);
transYAnim.setInterpolator(new TimeInterpolator() {
          @Override
          public float getInterpolation(float input) {
                 return input;
           }
          });

transYAnim.setEvaluator(new TypeEvaluator<Float>() {
//根据当前进度,使View在Y轴上实现正弦曲线运动
              @Override
              public Float evaluate(float fraction, Float startValue, Float endValue) {
              return (float) Math.sin(fraction * 4 * Math.PI) * (endValue - startValue);
              }
             });