Android 動畫

視圖動畫:

AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation 和 動畫集:AnimationSet

  • AlphaAnimation(透明度動畫):
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(1000);
view.startAnimation(alphaAnimation);
  • RotateAnimation(旋轉動畫):
RotateAnimation rotateAnimation = new RotateAnimation(0, 360, 
RotateAnimation.RELATIVE_TO_SELF, 0.5F, RotateAnimation.RELATIVE_TO_SELF, 0.5F);
rotateAnimation.setDuration(1000);
view.startAnimation(rotateAnimation);
  • TranslateAnimation(位移動畫):
TranslateAnimation  translateAnimation = new TranslateAnimation(0, 200, 0, 0);
translateAnimation.setDuration(1000);
view.startAnimation(translateAnimation);
  • ScaleAnimation(縮放動畫):
ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1, 
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(1000);
view.startAnimation(scaleAnimation);
  • AnimationSet(動畫集合):
AnimationSet animationSet = new AnimationSet(true);
        animationSet.setDuration(4000);
        animationSet.addAnimation(alphaAnimation);
        animationSet.addAnimation(rotateAnimation);
        animationSet.addAnimation(translateAnimation);
        animationSet.addAnimation(scaleAnimation);
        animationSet.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                Log.e(TAG, "onAnimationStart: 動畫開始執(zhí)行的時候調(diào)用");
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Log.e(TAG, "onAnimationEnd: 動畫結束執(zhí)行的時候調(diào)用");
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                Log.e(TAG, "onAnimationRepeat: 動畫重復執(zhí)行的時候調(diào)用");
            }
        });
//啟動動畫
view.startAnimation(animationSet);

屬性動畫

PropertyValuesHolder、Animator、ObjectAnimator 、ValueAnimator

  • ObjectAnimator :

ObjectAnimator 是屬性動畫框架中最重要的實行類,創(chuàng)建一個ObjectAnimator只需要通過它的靜態(tài)工廠類直接返回一個ObjectAnimator對象.(通過ofxxx方法);
必須具備get 、set方法,不然ObjectAnimator就無法起效;

  • 1.translationX 和 translationY:控制view對象從布局容器的左下方坐標偏移的位置;
  • 2.rotation 、rotationX 和 rotationY:控制view對象圍繞它的支點進行2D和3D旋轉;
  • 3.scaleX 和 scaleY: 控制view對象圍繞它的支點進行2D縮放;
  • 4.pivotX 和 pivotY:這兩個屬性控制著View對象的支點位置, 圍繞這個支點進行旋轉和縮放變換處理;
    默認情況下,該支點的位置就是view的中心點;
  • 5.alpha:它表示view對象的alpha透明度,默認值是1(不透明) ,0代表完全透明(不可見);
    如果沒有get set方法,那么可以自定義一個屬性或者包裝類,來間接地給這個屬性增加get set方法, 或者通過ValueAnimator來實現(xiàn);
  1. 自帶屬性:
ObjectAnimator  objectAnimator = ObjectAnimator.ofFloat(view, "translationX", 200);
objectAnimator.setDuration(1000);
objectAnimator.start();

 ObjectAnimator animatorColor = ObjectAnimator.ofInt(view,"BackgroundColor",0xffff0000,0xff00ff00);
animatorColor.setEvaluator(new ArgbEvaluator());
animatorColor.setDuration(1000);
animatorColor.start();
  1. 自定義屬性:
public class WrapperView {

    private View view;

    public WrapperView(View view) {
        this.view =view;
    }

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

    public void setWidth(int width) {
        view.getLayoutParams().width = width;
        view.requestLayout();
    }
}

WrapperView wrapperView = new WrapperView(tvWrapper);
ObjectAnimator objectAnimatorWrapper = ObjectAnimator.ofInt(wrapperView, "width", 100).setDuration(1000);
        objectAnimatorWrapper.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                Log.e(TAG, "onAnimationStart: 動畫開始執(zhí)行的時候調(diào)用");
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                //這個應該是用得最多的吧
                Log.e(TAG, "onAnimationEnd: 動畫結束執(zhí)行的時候調(diào)用");
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                Log.e(TAG, "onAnimationEnd: 動畫取消執(zhí)行的時候調(diào)用");
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                Log.e(TAG, "onAnimationEnd: 動畫重復執(zhí)行的時候調(diào)用");
            }
        });
objectAnimatorWrapper.start();

  • PropertyValuesHolder:

類似AnimationSet

  1. 動畫合并:
PropertyValuesHolder valuesHolderTranslastion = PropertyValuesHolder.ofFloat("translationX", 100f);
PropertyValuesHolder valuesHolderScaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.3f);
PropertyValuesHolder valuesHolderScaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.3f);
PropertyValuesHolder valuesHolderColor = PropertyValuesHolder.ofInt("BackgroundColor", 0xff888888, 0xff00ff00);
ObjectAnimator objectAnimatorProper = ObjectAnimator.ofPropertyValuesHolder(tvObjProperty, valuesHolderTranslastion, valuesHolderScaleX, valuesHolderScaleY, valuesHolderColor);
objectAnimatorProper.setDuration(1000);
objectAnimatorProper.start();
  1. 動畫拆分:
 // 在 0% 處開始向X移動
Keyframe keyframe1 = Keyframe.ofFloat(0, 0);
// 時間經(jīng)過 50% 的時候,動畫完成度 100%
Keyframe keyframe2 = Keyframe.ofFloat(0.5f, 100);
// 時間見過 100% 的時候,動畫完成度倒退到 0%位置
Keyframe keyframe3 = Keyframe.ofFloat(1, 0);
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationX", keyframe1, keyframe2, keyframe3);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(tvObjPropertyKey, holder);
animator.start();

  • ValueAnimator:

ValueAnimator 是 ObjectAnimator 的父類,ValueAnimator 就是一個不能指定目標對象版本的 ObjectAnimator

ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,1000);
        valueAnimator.setTarget(view);
        valueAnimator.setDuration(1000);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
              // TODO: 2018/10/24
                float value = (float) animation.getAnimatedValue();
                if (value==500f){
                    ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                    scaleAnimation.setDuration(100);
                    view.startAnimation(scaleAnimation);
                }
            }
        });

  • Animator:

res/animator下創(chuàng)建布局文件,代碼加載xml布局文件

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="scaleX"
    android:valueFrom="1.0"
    android:valueTo="2.0"
    android:valueType="floatType">
</objectAnimator>

Animator animatorXml = AnimatorInflater.loadAnimator(MainActivity.this,R.animator.animator_xml);
animatorXml.setTarget(view);
animatorXml.start();

AnimationUtils (工具類)

  • Android SDK 提供的工具類:
返回值 公共方法 描述
static long currentAnimationTimeMillis() 以毫秒返回當前動畫時間
static Animation loadAnimation(Context context, int id) 從資源加載動畫對象
static Interpolator loadInterpolator(Context context, int id) 從資源中加載內(nèi)插器對象
static LayoutAnimationController loadLayoutAnimation(Context context, int id) 從資源加載動畫對象(返回值不同)
static Animation makeInAnimation(Context c, boolean fromLeft) 用布爾參數(shù)決定滑入的方向是左側還是右側向上
static Animation makeInChildBottomAnimation(Context c) 視圖總是從屏幕的底部向上滑入
static Animation makeOutAnimation(Context c, boolean toRight) 用布爾參數(shù)決定滑入的方向是左側還是右側
animation = AnimationUtils.loadAnimation(this, R.anim.animation_utils);
view.startAnimation(animation);

ViewAnimationUtils (5.X的工具類)

createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius)

  • centerX : 中心點X坐標;
  • centerY : 中心點Y坐標;
  • startRadius: 動畫圓的起始半徑;
  • endRadius: 動畫圓的結束半徑.
ViewAnimationUtils.createCircularReveal(ImageView, centerX, centerY, mImageView.getWidth(), 0);

Interpolator(插值器)

Interpolator 其實就是速度設置器。你在參數(shù)里填入不同的 Interpolator ,動畫就會以不同的速度模型來執(zhí)行;Google TimeInterpolator

  • AccelerateDecelerateInterpolator:

先加速再減速。這是默認的 Interpolator;

  • LinearInterpolator:

勻速;

  • AccelerateInterpolator:

持續(xù)加速;

  • DecelerateInterpolator:

以最高速開始,持續(xù)減速直到停止;

  • AnticipateInterpolator:

先回退一下段,然后再正常運動;

  • OvershootInterpolator:

到終點的時候超出一下段,然后彈回來;

  • AnticipateOvershootInterpolator:

開始前回拉,最后超過一些然后回彈;

  • BounceInterpolator:

到達終點的時候彈回來兩下,然后回到終點;

  • CycleInterpolator:

這個也是一個正弦 / 余弦曲線,不過它和 AccelerateDecelerateInterpolator 的區(qū)別是,它可以自定義曲線的周期,所以動畫可以不到終點就結束,也可以到達終點后回彈,回彈的次數(shù)由曲線的周期決定,曲線的周期由 CycleInterpolator() 構造方法的參數(shù)決定。

  • PathInterpolator:

自定義動畫完成度 / 時間完成度曲線。
用這個 Interpolator 你可以定制出任何你想要的速度模型。定制的方式是使用一個 Path 對象來繪制出你要的動畫完成度 / 時間完成度曲線

  • FastOutLinearInInterpolator(5.0以上):

貝塞爾曲線的持續(xù)加速的運動路線,AccelerateInterpolator比FastOutLinearInInterpolator斜率要低一點;

  • FastOutSlowInInterpolator(5.0以上):

貝塞爾曲線,前期加速度要快得多;

  • LinearOutSlowInInterpolator(5.0以上):

減速曲線,初始速度更高;


SVG(矢量動畫)

  • Android 5.X增加了對SVG矢量圖的支持(VectorDrawable,AnimatedVectorDrawable):
    <path>標簽支持的指令:
  • M: 移動 moveTo;
  • L: 直線;
  • H: 水平線;
  • V: 垂直線;
  • C: 三次貝塞爾曲線;
  • S: 三次貝塞爾曲線;
  • Q: 二次貝塞爾曲線;
  • T: 映射前面路徑后的終點;
  • Z: 關閉路徑;
  • A: 弧線;
  • RX,RY表示橢圓半圓的半軸大?。?/li>
  • XROTATION表示X軸與水平方向的順時針方向的夾角;
  • FLAG1有兩個值:1.表示大角度的弧線,0.表示小角度弧線;
  • FLAG2有兩個值,確定從起點至終點的方向:1.表示順時針,0.表示逆時針;
  • X,Y軸為終點坐標;

1.大小寫效果一樣,2.坐標軸和canvas一樣左上角(0,0),3.指令和數(shù)據(jù)間的空格可以省略,4.同個指令出現(xiàn)多個時候可以只用一個。

   defaultConfig {
        //配置信息
        vectorDrawables.useSupportLibrary = true
    }
<!--res/drawable下新建-->
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="100dp"
    android:width="100dp"
    android:viewportWidth="100"
    android:viewportHeight="100">
    <group>
        <path
            android:name="path1"
            android:strokeColor="@color/colorPrimaryDark"
            android:strokeWidth="5"
            android:strokeLineCap="round"
            android:pathData="M 20,80 L 50,80 80,80"/>
    </group>

    <group>
        <path
            android:name="path2"
            android:strokeColor="@color/colorPrimaryDark"
            android:strokeWidth="5"
            android:strokeLineCap="round"
            android:pathData="M 20,20 L 50,20 80,20"/>
    </group>
</vector>


<!--res/animator下新建-->
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:propertyName="pathData"
    android:valueFrom="M 20,80 L 50,80 80,80"
    android:valueTo="M 20,80 L 50,50 80,80"
    android:valueType="pathType"
    android:interpolator="@android:anim/bounce_interpolator">
</objectAnimator>

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:propertyName="pathData"
    android:valueFrom="M 20,20 L 50,20 80,20"
    android:valueTo="M 20,20 L 50,50 80,20"
    android:valueType="pathType"
    android:interpolator="@android:anim/bounce_interpolator">

</objectAnimator>

<!--res/drawble-v21下新建-->
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/svg_line">

    <target
        android:name="path1"
        android:animation="@animator/animator_svg_path1"/>

    <target
        android:name="path2"
        android:animation="@animator/animator_svg_path2"/>
</animated-vector>

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    Drawable drawable = imageViewSVG.getDrawable();
                    if (drawable instanceof Animatable){
                        ((Animatable) drawable).start();
                    }
                }

SVG編輯器鏈接
本項目的簡單Demo地址


最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 【Android 動畫】 動畫分類補間動畫(Tween動畫)幀動畫(Frame 動畫)屬性動畫(Property ...
    Rtia閱讀 6,452評論 1 38
  • 動畫基礎概念 動畫分類 Android 中動畫分為兩種,一種是 Tween 動畫、還有一種是 Frame 動畫。 ...
    Rtia閱讀 1,375評論 0 6
  • Animation Animation類是所有動畫(scale、alpha、translate、rotate)的基...
    四月一號閱讀 2,037評論 0 10
  • 目前我的工作是法語導游,接待法語國家的游客來我國游玩。我的法語是自學的,所以想和對法語有興趣的同學分享一下。 1....
    心的新旅行閱讀 464評論 7 1
  • 獨立思考的能力,我想這是我目前最欠缺的吧。人的惰性作祟,很多時候都奉行拿來主義。遇到問題不會,沒有通過自己的思考,...
    黑賽矩陣閱讀 191評論 2 1

友情鏈接更多精彩內(nèi)容