美文网首页
Android中动画的种类和实现

Android中动画的种类和实现

作者: simit | 来源:发表于2019-01-22 14:57 被阅读0次

    Android 中的动画有三种类型:
    View Animation(补间动画):只能设置给View,可以进行位置,大小,旋转,透明四种变化。(xml = anim)
    Drawable Animation(帧动画):用来一个个的显示图片资源,类似于幻灯片一帧一帧地播放。(xml = drawable)
    Property Animation(属性动画):Android3.0以上系统中使用,这种动画可以设置给任何object并且是可以扩展的,可以自定义任何类型和属性的动画。(xml = animator)
    View Animation(补间动画):
    补间动画可以对View进行位置,大小,旋转,透明度四种变化,但是值得注意的是补间动画并没有真正改变View的属性,也就是说一个Button 进行位移动画,则位移之后的位置并不能响应这个Button的点击事件,而在Button的初始位置才能响应Button的点击事件。
    补间动画的实现:
    补间动画可以在xml里定义,也可以在代码中定义,这里演示xml定义。
    补间动画要在res/anim文件夹中定义

    <?xml version="1.0" encoding="utf-8"?>
    
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillBefore="true">
        <!---android:fillAfter="true" 停留在动画之后的位置-->
        <!---android:fillBefore="true" 动画结束后回到之前的位置-->
    <translate
        android:duration="5000"
        android:fromXDelta="100"
        android:fromYDelta="100"
        android:toXDelta="500"
        android:toYDelta="500" />
    </set>
    

    代码中加载这个动画并start即可

    Animation animation = AnimationUtils.loadAnimation(this, R.anim.view1);
    view.startAnimation(animation);
    

    xml 中也可以定义动画的集合

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="5000"
        android:fillBefore="true">
    
        <translate
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="500"
            android:toYDelta="500" />
        <alpha
            android:fromAlpha="1"
            android:toAlpha="0.2" />
    
    
        <!--android:pivotX="50%"-->
        <!--android:pivotY="50%"    中心点坐标-->
    
    
    
        <rotate
            android:fromDegrees="0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="7200" />
        <scale
            android:fromXScale="1"
            android:fromYScale="1"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toXScale="5"
            android:toYScale="5"/>
    
    </set>
    

    使用方式和上面一致。
    插值器(Interpolator):
    插值器反映的是动画执行的变化率,也就是动画从初始位置到结束位置的执行过程中是加速,减速还是其他复杂过程,简单说动画的执行过程就是插值器。
    Android系统提供了AccelerateDecelerateInterpolator,BounceInterpolator等插值器,当然也可以自定义插值器,只需实现Interpolator接口即可。

    /**
     * 自定义插值器只需要实现Interpolator接口即可
     */
    public class MyInterpolator implements Interpolator {
        private static final String TAG = "MyInterpolator";
    
        /**
         * input 是一个0 --> 1 的值
         *
         * @param input
         * @return 返回值也是一个0 ---> 1 左右的值 反映的是变化速率
         */
        @Override
        public float getInterpolation(float input) {
            Log.i(TAG, "input ====> " + input);
            float rate = 0;
            if (input <= 0.2) {
                rate = 0.2f;
            } else if (input <= 0.3) {
                rate = 0.4f;
            } else if (input <= 0.4) {
                rate = 0.5f;
            } else if (input <= 0.5) {
                rate = 0.6f;
            } else if (input <= 0.7) {
                rate = 0.7f;
            } else if (input <= 0.8) {
                rate = 0.8f;
            } else if (input <= 0.9) {
                rate = 0.9f;
            } else {
                rate = 0;
            }
            Log.i(TAG, "插值器 " + rate);
            return rate;
        }
    }
    

    使用时只需:

    animation.setInterpolator(new MyInterpolator());
    

    Drawable Animation(帧动画):
    是对图片资源一帧一帧地播放,但是要注意图片资源不能过大否则会OOM。
    使用:
    在res/drawable文件下新建xml

    <?xml version="1.0" encoding="utf-8"?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:drawable="@mipmap/a_0"
            android:duration="200"/>
    
        <item android:drawable="@mipmap/a_1"
            android:duration="200"/>
    
        <item android:drawable="@mipmap/a_2"
            android:duration="200"/>
    
    </animation-list>
    

    设置图片资源和播放时长,并在布局中引用 android:src="@drawable/frame1"

    <ImageView
            android:id="@+id/frame1"
            android:layout_marginTop="50dp"
            android:src="@drawable/frame1"
            android:layout_centerHorizontal="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    

    之后java中start即可

    AnimationDrawable drawable = (AnimationDrawable) frame.getDrawable();
            drawable.start();
    

    Property Animation(属性动画):
    属性动画是Android3.0之后引入,是通过不断修改属性来实现各种动画效果。属性动画有三个重要的类:
    ValueAnimator,ObjectAnimator(继承自ValueAnimator),Animatorset(动画集合)。
    学习属性动画之前先介绍下Evaluator(估值器):
    估值器是属性动画特有的,是定义属性值从初始值过度到结束值的变化的具体数值。
    插值器和估值器的区别:
    插值器决定的是变化规律(加速,减速),而具体的变化数值则交给估值器(即估值器决定的是动画中属性改变的值)。
    自定义估值器只需实现TypeEvaluator接口即可:

    /**
     * 自定义估值器 ofObject
     */
    public class MyObjectEvaluator implements TypeEvaluator{
        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            float startFloat = ((Number) startValue).floatValue();
            float endFloat = ((Number) endValue).floatValue();
            float v = fraction * (endFloat - startFloat);
            Log.i("MyInterpolator","估值器 "+v);
            return v;
        }
    }
    

    ValueAnimator 的使用:

           ValueAnimator valueAnimator = ValueAnimator.ofFloat(frame.getLayoutParams().width, frame.getLayoutParams().width+500);
            valueAnimator.setDuration(2000);//设置动画播放时长
    //        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
    //        valueAnimator.setRepeatCount(1000);
            //设置插值器
            valueAnimator.setInterpolator(new MyInterpolator());
            //设置估值器
            valueAnimator.setEvaluator(new MyObjectEvaluator());
            valueAnimator.start();
            //设置更新监听器
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    //currentValue 即为估值器的返回值
                    float currentValue = (float) animation.getAnimatedValue();
                    //获取每次变化后的属性值
                    Log.i("currentValue","currentValue ====> "+currentValue);
                    //将每次变化手动赋值给对象的属性
                    frame.getLayoutParams().width = Float.valueOf(currentValue).intValue();
                    //视图重绘实现动画效果
                    frame.requestLayout();
    
                }
            });
    

    ValueAnimator 有三个重要方法:
    ValueAnimator.ofInt(int values)以整形进行动画过度
    ValueAnimator.ofFloat(float values)以浮点型进行动画过度
    ValueAnimator.ofObject(int values)以对象进行动画过度

    ObjectAnimator的使用(java):

     ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(viewList.get(i),"translationY",300f * i,0);
     objectAnimator.setDuration(500);
     objectAnimator.setStartDelay(i * 300);
    objectAnimator.start();
    

    ObjectAnimator是ValueAnimator的子类,不需要监听动画的更新过程,也就是说ObjectAnimator是自动实现了属性的赋值过程而不需要手动设置,这样需要保证属性必须有get(该属性没有初始值的话)和set方法。
    当需要同时修改多个属性时可以使用PropertyValuesHolder:

     PropertyValuesHolder a = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);
     PropertyValuesHolder b = PropertyValuesHolder.ofFloat("scaleX", 1f, 0);
     ObjectAnimator.ofPropertyValuesHolder(viewList.get(i), a, b).setDuration(2000).start();
    

    Animatorset(动画集合):

    set.playTogether();//集合中的动画同时执行
    set.playSequentially();//集合中的动画顺序执行
    set.play(a).with(b);//a和b同时执行
    set.play(a).after(b);//a在b之后执行
    

    相关文章

      网友评论

          本文标题:Android中动画的种类和实现

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