Android 之动画机制

简单介绍

在我们的项目中,动画是必不可少的一部分,包括Activity的转场,点击控件、图片、文字的效果。

那么动画主要分为四种:

1.逐帧动画 Frame Animation:这个比较简单,通过用图片,一帧一帧的播放出来,就像早期的动漫。

2.补间动画 Tween Animation:通过在xml文件中定义属性,进行平移,旋转、透明、缩放等功能。

3.属性动画 Property Animation:可以直接改变动画的属性,也可进行平移,旋转、透明、缩放等功能。

4.过渡动画 Transition Animation:实现Activity或View过渡动画的效果。


逐一介绍

1.逐帧动画:这种动画相信大家都非常的了解,主要实现他的方法是通过在xml文件当中的Drawble当中,添加item(属性分别为:一帧的时间,图片id)

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@mipmap/audio_anim_01" android:duration="200" />
    <item android:drawable="@mipmap/audio_anim_02" android:duration="200" />
    <item android:drawable="@mipmap/audio_anim_03" android:duration="200" />
    <item android:drawable="@mipmap/audio_anim_04" android:duration="200" />
    <item android:drawable="@mipmap/audio_anim_05" android:duration="200" />
    <item android:drawable="@mipmap/audio_anim_06" android:duration="200" />
    <item android:drawable="@mipmap/audio_anim_07" android:duration="200" />
    <item android:drawable="@mipmap/audio_anim_08" android:duration="200" />
    <item android:drawable="@mipmap/audio_anim_09" android:duration="200" />
</animation-list>

其次我们需要使用代码的方式实现简单的逻辑:

Image.setBackground(drawable);
//获取对象实例,用来控制播放与停止
AnimationDrawable rocketAnimation = (AnimationDrawable) Image.getBackground();
rocketAnimation.start();    // 开启帧动画
rocketAnimation.stop();     // 停止动画

2.补间动画:也是在xml文件当中添加一些属性,在代码中调用,如果要同时实现多种效果,须写到set中.

(1)属性介绍:

    XML:

alph                   渐变透明度动画效果
scale                  渐变尺寸伸缩动画效果
translate              画面转换位置移动动画效果
rotate                 画面转移旋转动画效果

     代码:

AlphaAnimation         渐变透明度动画效果
ScaleAnimation         渐变尺寸伸缩动画效果
TranslateAnimation     画面转换位置移动动画效果
RotateAnimation        画面转移旋转动画效果

  (1)那么这四个效果在xml中为:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <alpha
        android:duration="2000"
        android:fromAlpha="0"
        android:toAlpha="1" />
    <translate
        android:duration="2000"
        android:fromXDelta="100%"
        android:fromYDelta="100%"
        android:toXDelta="0%"
        android:toYDelta="0%"
        android:duration="2000"
        android:fillAfter="true"/>
    <rotate
        android:duration="2000"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="3000"/>
    <scale 
        android:duration="2000"
        android:fromXScale="1"
        android:toXScale="2"
        android:fromYScale="1"
        android:toYScale="2"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="3000"/>
</set>

  (2)那么这四个效果在java中为:

//透明:
AlphaAnimation alpha = new AlphaAnimation(0, 1);
alpha.setDuration(500);          //设置持续时间
alpha.setFillAfter(true);                   //动画结束后保留结束状态
alpha.setInterpolator(new AccelerateInterpolator());        //添加差值器
ivImage.setAnimation(alpha);


//缩放:
ScaleAnimation scale = new ScaleAnimation(1.0f, scaleXY, 1.0f, scaleXY, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scale.setDuration(durationMillis);
scale.setFillAfter(true);
ivImage.setAnimation(scale);

//平移:
TranslateAnimation translate = new TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);
translate.setDuration(durationMillis);
translate.setFillAfter(true);
ivImage.setAnimation(translate);

//旋转:
RotateAnimation rotate = new RotateAnimation(fromDegrees, toDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(durationMillis);
rotate.setFillAfter(true);
ivImage.setAnimation(rotate);

3.属性动画:比补间动画的代码量少,功能强大了很多,但是只可以对继承于view的控件操作。

// 步骤1:设置需要组合的动画效果
ObjectAnimator translation = ObjectAnimator.ofFloat(mButton, "translationX", curTranslationX, 300,curTranslationX); 
// 平移动画
ObjectAnimator rotate = ObjectAnimator.ofFloat(mButton, "rotation", 0f, 360f); 
// 旋转动画
ObjectAnimator alpha = ObjectAnimator.ofFloat(mButton, "alpha", 1f, 0f, 1f); 
// 透明度动画
// 步骤2:创建组合动画的对象
AnimatorSet animSet = new AnimatorSet(); 
// 步骤3:根据需求组合动画
animSet.play(translation).with(rotate).before(alpha); 
animSet.setDuration(5000); 
// 步骤4:启动动画
animSet.start();

插值器:interpolator 决定值的变化模式

AccelerateInterpolator 加速,开始时慢中间加速
DecelerateInterpolator 减速,开始时快然后减速
AccelerateDecelerateInterolator 先加速后减速,开始结束时慢,中间加速
AnticipateInterpolator 反向,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator 反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2* mCycles* Math.PI* input)
LinearInterpolator 线性,线性均匀改变
OvershootInterpolator超越,最后超出目的值然后缓慢改变到目的值
PathInterpolator新增的,就是可以定义路径坐标,然后可以按照路径坐标来跑动;注意其坐标并不是 XY,而是单方向,也就是我可以从0~1,然后弹回0.5 然后又弹到0.7 有到0.3,直到最后时间结束。

4.过渡动画是指以动画的形式实现View两个场景的切换(从一个场景切换到另一个场景)。而且在切换过程中通过Transition来设置不同的过渡动画效果

1.style文件主题里面统一定义,全局为所有Activity设置过渡动画效果

<item name="android:windowAnimationStyle">@style/Animation.Activity.Customer</item>

  <style name="Animation.Activity.Customer" parent="@android:style/Animation.Activity">
        <!-- 进入一个新的Activity的时候,A->B B进入动画 -->
        <item name="android:activityOpenEnterAnimation">@anim/right_in</item>
        <!-- 进入一个新的Activity的时候,A->B A退出动画 -->
        <item name="android:activityOpenExitAnimation">@anim/left_out</item>
        <!-- 退出一个Activity的时候,B返回到A A进入动画 -->
        <item name="android:activityCloseEnterAnimation">@anim/left_in</item>
        <!-- 退出一个Activity的时候,B返回到A B退出动画 -->
        <item name="android:activityCloseExitAnimation">@anim/right_out</item>
    </style>

2.通知transtion启动Activity:

ActivityOptions compat = ActivityOptions.makeSceneTransitionAnimation(mActivity);
startActivity(new Intent(mContext, MakeSceneTransitionctivity.class), compat.toBundle());

3.资源文件配置动画:

<?xml version="1.0" encoding="utf-8"?>
<slide xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000">
    <targets>
        <target android:excludeId="@android:id/statusBarBackground"/>
        <target android:excludeId="@android:id/navigationBarBackground"/>
    </targets>
</slide>

 4.定义动画顺序:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="sequential">
    <slide android:slideEdge="bottom">
        <targets>
            <target android:targetId="@id/image_shared" />
        </targets>
    </slide>

    <fade>
        <targets>
            <target android:excludeId="@android:id/statusBarBackground" />
            <target android:excludeId="@android:id/navigationBarBackground" />
            <target android:excludeId="@id/image_shared" />
        </targets>
    </fade>
</transitionSet>

5.代码核心:

//      //资源文件指定过渡动画
//      getWindow().setEnterTransition(TransitionInflater.from(this).inflateTransition(R.transition.transition_target));
//代码制定过渡动画
TransitionSet transitionSet = new TransitionSet();
//slide动画
Slide slide = new Slide(Gravity.BOTTOM);
slide.addTarget(R.id.image_shared);
transitionSet.addTransition(slide);
//fade动画
Fade fade = new Fade();
fade.excludeTarget(android.R.id.statusBarBackground, true);
fade.excludeTarget(android.R.id.navigationBarBackground, true);
fade.excludeTarget(R.id.image_shared, true);
transitionSet.addTransition(fade);
transitionSet.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
getWindow().setEnterTransition(transitionSet);

猜你喜欢

转载自blog.csdn.net/LoverLeslie/article/details/85164031