android動(dòng)畫

轉(zhuǎn)載出自:http://www.cnblogs.com/ldq2016/

Android動(dòng)畫

  • View Animation 視圖動(dòng)畫,只能用來設(shè)置View的動(dòng)畫
  • Drawable Animation 幀動(dòng)畫(Frame動(dòng)畫),一幀幀地顯示資源文件中的Drawable
  • Property Animation 屬性動(dòng)畫,在android3.0以上的系統(tǒng)才有。這動(dòng)畫可以設(shè)置給任何的Object,包括那些還沒有渲染到屏幕的view.

View Animation 視圖動(dòng)畫

視圖動(dòng)畫也叫補(bǔ)間動(dòng)畫,指在一個(gè)視圖容器中執(zhí)行一些變換。包含有:位置、大小、旋轉(zhuǎn)、透明
補(bǔ)間動(dòng)畫一般一般通過xml實(shí)現(xiàn),不建議是用android代碼實(shí)現(xiàn),因?yàn)榇a實(shí)現(xiàn)的可讀性比較差。

補(bǔ)間動(dòng)畫的相關(guān)類

  • AlphaAnimation <alpha>放在res/anim/目錄下 透明漸變動(dòng)畫效果
  • RotateAnimation <rotate>放在res/anim/目錄下 旋轉(zhuǎn)轉(zhuǎn)移動(dòng)畫效果
  • ScaleAnimation <scale>放在res/anim/目錄下 縮放動(dòng)畫效果
  • TranslateAnimation <translate>放在res/anim/目錄下 移動(dòng)動(dòng)畫效果
  • AnimationSet <set> 放在res/anim/目錄下 持有動(dòng)畫的容器

Animation屬性詳解

xml屬性 java方法 解釋
android:detachWallpaper setDetachWallpaper(boolean) 是否在壁紙上運(yùn)行
android:duration setDuration(long) 動(dòng)畫持續(xù)時(shí)間(毫秒)
android:fillAfter setFillAfter(boolean) 動(dòng)畫結(jié)束時(shí)是否保持動(dòng)畫最后的狀態(tài)
android:fillBefore setFillBefore(boolean) 動(dòng)畫結(jié)束時(shí)是否還原到動(dòng)畫開始的狀態(tài)
android:fillEnable setFillEnable(boolean) 與fillBefore效果相同
android:interpolator setInterpolator(Interpolator) 指定動(dòng)畫效果(插值器)
android:repeatCount setRepeatCount(int) 重復(fù)次數(shù)
android:repeatMode setRepeatMode(int) 設(shè)置重復(fù)類型,reverse倒序 restart從頭
android:startOffset setStartOffset(long) star開始后等待開始播放的時(shí)間
android:zAdjustment setZAdjustment(int) 動(dòng)畫的內(nèi)容運(yùn)行時(shí)在z軸上的位置(top/bottom/normal) 默認(rèn)normal

Alpha屬性詳解

xml屬性 java方法 解釋
android:fromAlpha AlphaAnimation(float fromAlpha,...) 動(dòng)畫開始的透明度(0.0到1.0)
android:toAlpha AlphaAnimation(...,float toAlpha) 動(dòng)畫結(jié)束的透明度

Rotate屬性詳解

xml屬性 java方法 解釋
android:fromDegrees RotateAnimation(float fromDegrees,...) 旋轉(zhuǎn)開始角度,正順時(shí)針,負(fù)逆時(shí)針
android:toDegrees RotateAnimation(...,float toDegrees,...) 旋轉(zhuǎn)結(jié)束角度,正順時(shí)針,負(fù)逆時(shí)針
android:pivotX RotateAnimation(...,floate pivotX,...) 縮放起點(diǎn)X坐標(biāo)(數(shù)值、百分?jǐn)?shù)、百分?jǐn)?shù)p,例如50表示以當(dāng)前view左上角坐標(biāo)加50px為初始點(diǎn),50%表示以當(dāng)前view左上角坐標(biāo)加上當(dāng)前view的寬高的50%做為初始點(diǎn),50%p表示以當(dāng)前view左上角加上父控件寬高的50%做為初始點(diǎn))
android:pivotY RotateAnimation(...,float pivotY) 縮放起點(diǎn)Y的坐標(biāo),與X的規(guī)律一樣

Scale屬性詳解

xml屬性 java方法 解釋
android:fromXScale ScaleAnimation(float fromX,...) 初始x軸縮放比例,1.0表示無變化
android:toXScale ScaleAnimation(...,float toX,...) 結(jié)束x軸縮放比例
android:fromYScale ScaleAnimation(...,float fromY,...) 初始Y軸縮放比例
android:toYScale ScaleAnimation(...,float toY,...) 結(jié)束y軸縮放比例
android:pivotX ScaleAnimation(...,floate pivotX,...) 縮放起點(diǎn)X坐標(biāo)(數(shù)值、百分?jǐn)?shù)、百分?jǐn)?shù)p,例如50表示以當(dāng)前view左上角坐標(biāo)加50px為初始點(diǎn),50%表示以當(dāng)前view左上角坐標(biāo)加上當(dāng)前view的寬高的50%做為初始點(diǎn),50%p表示以當(dāng)前view左上角加上父控件寬高的50%做為初始點(diǎn))
android:pivotY ScaleAnimation(...,float pivotY) 縮放起點(diǎn)Y的坐標(biāo),與X的規(guī)律一樣

Translate屬性詳情

xml屬性 java方法 解釋
android:fromXDelta TranslateAnimation(...,floate fromXDelta,...) 起點(diǎn)X軸坐標(biāo)(數(shù)值、百分?jǐn)?shù)、百分?jǐn)?shù)p,例如50表示以當(dāng)前view左上角坐標(biāo)加50px為初始點(diǎn),50%表示以當(dāng)前view左上角坐標(biāo)加上當(dāng)前view的寬高的50%做為初始點(diǎn),50%p表示以當(dāng)前view左上角加上父控件寬高的50%做為初始點(diǎn))
android:fromYDelta TranslateAnimation(...,float fromYDelta) 起點(diǎn)y軸坐標(biāo),與X的規(guī)律一樣
android:toXDelta TranslateAnimation(...,float toXDelta,...) 結(jié)束點(diǎn)x軸坐標(biāo),同上規(guī)律
android:toYDelta TranslateAnimation(...,float toYDelta) 結(jié)束點(diǎn)y軸坐標(biāo),同上規(guī)律

AnimationSet詳解

AnimationSet是集成Animation,是上面四種的組合容器類,沒有自己的特性

補(bǔ)間動(dòng)畫的使用

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:shareInterpolator=["true" | "false"] >
    <alpha
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float" />
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />
</set>
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.xxx);
image.startAnimation(hyperspaceJumpAnimation);
Animation常用方法 解釋
reset() 重置Animation的初始化
cancel() 取消Animation動(dòng)畫
start() 開始Animation動(dòng)畫
setAnimationListener(AnimationListener listener) 給當(dāng)前Animation設(shè)置動(dòng)畫監(jiān)聽
hasStarted() 判斷Animation是否開始
hasEnded() 判斷Animation是否結(jié)束
view常用動(dòng)畫操作方法 解釋
startAnimation(Animation animation) 對(duì)當(dāng)前view開始設(shè)置Animation動(dòng)畫
clearAnimation() 取消當(dāng)前view正在執(zhí)行的動(dòng)畫

注意一下,補(bǔ)間動(dòng)畫執(zhí)行后并沒有改變View的真實(shí)布局屬性

插值器Interpolator

java類 xml id 描述
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 動(dòng)畫始末速率慢,中間加速
AccelerateInterpolator @android:anim/accelerate_interpolator 動(dòng)畫開始速率較慢,之后慢慢加速
AnticipateInterpolator @android:anim/anticipate_interpolator 開始的時(shí)候從后向前甩
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 類似上面的AnticipateInterpolator
BounceInterpolator @android:anim/bounce_interpolator 動(dòng)畫結(jié)速時(shí)彈起
CycleInterpolator @android:anim/cycle_interpolator 循環(huán)播放速率改成正弦曲線
DecelerateInterpolator @android:anim/decelerate_interpolator 動(dòng)畫開始快然后慢
LinearInterpolator @android:anim/linear_interpolator 動(dòng)畫勻速改變
OvershootInterpolator @android:anim/overshoot_interpolator 向前彈出一定值之后回到原來的位置
PathInterpolate 新增,定義路徑坐標(biāo)后按照路徑坐標(biāo)

以上是系統(tǒng)提供的插值器

插值器的使用

<set android:interpolator="@android:anim/accelerate_interpolator">
  
</set>

插值器自定義

xml自定義
  1. 在res/anim/目錄下創(chuàng)建xml文件
  2. 修改
<?xml version="1.0" encoding="utf-8"?>
<InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"
    android:attribute_name="value"
    />
  1. 在你的補(bǔ)間動(dòng)畫中引用該文件
    在xml中,有些插值器是不具備修改屬性,具體如下:
  • <accelerateDecelerateInterpolator> 無可自定義的attribute
  • <accelerateInterpolator> android:factor float 加速速率(默認(rèn)為1)
  • <anticipateInterpolator> android:tension float 起始點(diǎn)后拉的張力數(shù)(默認(rèn)為2)
  • <anticipateOvershootInterpolator> android:tension android:extraTension float 拉力的倍數(shù)
  • <bounceInterpolator> 無可自定義的attribute
  • <cycleInterpolator> android:cycle int 循環(huán)的個(gè)數(shù)(默認(rèn)為1)
  • <decelerateInterpolator> android:factor float 減速的速率(默認(rèn)為1)
  • <linearInterpolator> 無可自定義的attribute
  • <overshootInterpolator> android:factor float 超出終點(diǎn)的張力(默認(rèn)為2)
java自定義

java自定義插值器是xml的升級(jí),所有的Interpolator都實(shí)現(xiàn)力Interpolator的接口,而Interpolator接口又繼承自TimeInterpolator。TimeInterpolator接口定義了一個(gè)float getInterpolator(float input)方法,這個(gè)方法是由系統(tǒng)調(diào)用的,其中參數(shù)input代表動(dòng)畫的時(shí)間,在0和1之間,也就是開始和結(jié)束之間。

public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    ......
    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }
    ......
}

Drawable動(dòng)畫(幀動(dòng)畫)

Drawable動(dòng)畫就是幀動(dòng)畫,它允許你實(shí)現(xiàn)像幻燈片一樣的效果,這種動(dòng)畫的實(shí)質(zhì)就是drawable.

Drawable動(dòng)畫的詳細(xì)說明

推薦使用xml的方式實(shí)現(xiàn)
<animation-list>必須是根節(jié)點(diǎn),包含一個(gè)或多個(gè)item屬性有:

  • android:oneshot true代表執(zhí)行一次,false代表無限循環(huán)
  • <item> 動(dòng)畫資源
    <item> animation-list的子項(xiàng),屬性有:
  • android:drawable 動(dòng)畫資源文件
    -android:duration 一幀顯示多長時(shí)間
<!-- 注意:文件位于res/drawable/目錄下 -->
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >
    <item
        android:drawable="@drawable/drawable_resource_name"
        android:duration="100" />
</animation-list>
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);

rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();

AnimationDrawable的start()方法不能在Activity的onCreate方法中運(yùn)行。因?yàn)锳nimationDrawable還未完全附在window上,所以最好的時(shí)間是在onWindowFocusChanged

Property Animation(屬性動(dòng)畫)

屬性動(dòng)畫是在Android3.0之后引入的,主要是通過改變控件的屬性來實(shí)現(xiàn)動(dòng)畫。

ObjectAnimation

繼承自ValueAnimation,允許你指定要進(jìn)行的動(dòng)畫對(duì)象以及對(duì)象的一個(gè)屬性。該類會(huì)根據(jù)計(jì)算得到新的值自動(dòng)更新屬性。
objectAnimation類提供了ofInt,ofFloat,ofObject這三個(gè)常用的方法,這些方法都是設(shè)置動(dòng)畫作用的元素、屬性、開始、結(jié)束等任意屬性值。當(dāng)屬性值是一個(gè)參數(shù)時(shí),就會(huì)通過getXX反射獲取的值作為起點(diǎn),設(shè)置的值作為終點(diǎn);當(dāng)屬性值是兩個(gè)參數(shù)時(shí),一個(gè)是開始另一個(gè)是結(jié)束。

我們通常使用ObjectAnimation設(shè)置view的屬性來生成動(dòng)畫,而一般View已知屬性變化時(shí)會(huì)主動(dòng)觸發(fā)繪制,所以動(dòng)畫會(huì)自動(dòng)實(shí)現(xiàn);但是也有特殊情況,例如Object不是view,或者作用的屬性沒有觸發(fā)重新繪制,或者我們?cè)谥乩L時(shí)需要做自己的操作,可以通過一下的方法實(shí)現(xiàn)

ObjectAnimator mObjectAnimator= ObjectAnimator.ofInt(view, "customerDefineAnyThingName", 0,  1).setDuration(2000);
mObjectAnimator.addUpdateListener(new AnimatorUpdateListener()
        {
            @Override
            public void onAnimationUpdate(ValueAnimator animation)
            {
                //int value = animation.getAnimatedValue();  可以獲取當(dāng)前屬性值
                //view.postInvalidate();  可以主動(dòng)刷新
                //view.setXXX(value);
                //view.setXXX(value);
                //......可以批量修改屬性
            }
        });
PropertyValuesHolder

多屬性動(dòng)畫同時(shí)工作管理類

PropertyValuesHolder a1 = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);  
PropertyValuesHolder a2 = PropertyValuesHolder.ofFloat("translationY", 0, viewWidth);  
......
ObjectAnimator.ofPropertyValuesHolder(view, a1, a2, ......).setDuration(1000).start();
AnimationSet

動(dòng)畫集合,提供把多個(gè)動(dòng)畫組合成一個(gè)組合的機(jī)制,而且還可以設(shè)置動(dòng)畫的時(shí)序關(guān)系(同時(shí)播放,順序播放,延遲播放)

ObjectAnimator a1 = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0f);  
ObjectAnimator a2 = ObjectAnimator.ofFloat(view, "translationY", 0f, viewWidth);  
......
AnimatorSet animSet = new AnimatorSet();  
animSet.setDuration(5000);  
animSet.setInterpolator(new LinearInterpolator());   
//animSet.playTogether(a1, a2, ...); //兩個(gè)動(dòng)畫同時(shí)執(zhí)行  
animSet.play(a1).after(a2); //先后執(zhí)行
......//其他組合方式
animSet.start();  
Interpolators
  • AccelerateDecelerateInterpolator 先加速后減速
  • AccelerateInterpolator 加速
  • DecelerateInterpolate 減速
  • AnticipateInterpolate 先向相反方向改變一段再加速播放
  • AnticipateOvershootInterpolate 先向相反方向改變,再加速播放,超出目標(biāo)后彈回
  • BounceInterpolate 快到目標(biāo)時(shí)跳躍
  • CycleInterpolate 動(dòng)畫循環(huán)一定次數(shù),值的改變?yōu)橐徽液瘮?shù):Math.sin(2 * mCycles * Math.PI * input)。
  • LinearInterpolate 線性勻速
    -OvershotInterpolate 最后超出目標(biāo)值后緩慢改變到目標(biāo)值
  • TimeInterpolate 一個(gè)允許自定義Interpolator的接口,以上都實(shí)現(xiàn)了該接口
//開始很慢然后不斷加速的插值器。
public class AccelerateInterpolator implements Interpolator {
    private final float mFactor;
    private final double mDoubleFactor;

    public AccelerateInterpolator() {
        mFactor = 1.0f;
        mDoubleFactor = 2.0;
    }

    ......

    //input  0到1.0。表示動(dòng)畫當(dāng)前點(diǎn)的值,0表示開頭,1表示結(jié)尾。
    //return  插值。值可以大于1超出目標(biāo)值,也可以小于0突破低值。
    @Override
    public float getInterpolation(float input) {
        //實(shí)現(xiàn)核心代碼塊
        if (mFactor == 1.0f) {
            return input * input;
        } else {
            return (float)Math.pow(input, mDoubleFactor);
        }
    }
}
Java屬性動(dòng)畫拓展之ViewPropertyAnimator動(dòng)畫
public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
     ......
     /**
     * This method returns a ViewPropertyAnimator object, which can be used to animate
     * specific properties on this View.
     *
     * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
     */
    public ViewPropertyAnimator animate() {
        if (mAnimator == null) {
            mAnimator = new ViewPropertyAnimator(this);
        }
        return mAnimator;
    }
    ......
}

ViewPropertyAnimator提供了一種非常方便的方法為View的部分屬性設(shè)置動(dòng)畫(切記,是部分屬性),它可以直接使用一個(gè) Animator對(duì)象設(shè)置多個(gè)屬性的動(dòng)畫;在多屬性設(shè)置動(dòng)畫時(shí),它比 上面的ObjectAnimator更加牛逼、高效,因?yàn)樗麜?huì)管理多個(gè)屬性的invalidate方法統(tǒng)一調(diào)運(yùn)觸發(fā),而不像上面分別調(diào)用,所以還會(huì)有一些 性能優(yōu)化

Java屬性動(dòng)畫拓展之LayoutAnimator容器布局動(dòng)畫

Property動(dòng)畫系統(tǒng)還提供了對(duì)ViewGroup中View添加時(shí)的動(dòng)畫功能,我們可以用LayoutTransition對(duì) ViewGroup中的View進(jìn)行動(dòng)畫設(shè)置顯示。LayoutTransition的動(dòng)畫效果都是設(shè)置給ViewGroup,然后當(dāng)被設(shè)置動(dòng)畫的 ViewGroup中添加刪除View時(shí)體現(xiàn)出來。該類用于當(dāng)前布局容器中有View添加、刪除、隱藏、顯示等時(shí)候定義布局容器自身的動(dòng)畫和View的動(dòng) 畫,也就是說當(dāng)在一個(gè)LinerLayout中隱藏一個(gè)View的時(shí)候,我們可以自定義 整個(gè)由于LinerLayout隱藏View而改變的動(dòng)畫,同時(shí)還可以自定義被隱藏的View自己消失時(shí)候的動(dòng)畫等。
LayoutTransition類中主要有五種容器轉(zhuǎn)換動(dòng)畫類型,具體如下:

  • LayoutTransition.APPEARING:當(dāng)View出現(xiàn)或者添加的時(shí)候View出現(xiàn)的動(dòng)畫。
  • LayoutTransition.CHANGE_APPEARING:當(dāng)添加View導(dǎo)致布局容器改變的時(shí)候整個(gè)布局容器的動(dòng)畫。
  • LayoutTransition.DISAPPEARING:當(dāng)View消失或者隱藏的時(shí)候View消失的動(dòng)畫。
  • LayoutTransition.CHANGE_DISAPPEARING:當(dāng)刪除或者隱藏View導(dǎo)致布局容器改變的時(shí)候整個(gè)布局容器的動(dòng)畫。
  • LayoutTransition.CHANGE:當(dāng)不是由于View出現(xiàn)或消失造成對(duì)其他View位置造成改變的時(shí)候整個(gè)布局容器的動(dòng)畫。

轉(zhuǎn)載這篇文章,彌補(bǔ)了我的在動(dòng)畫上的欠缺。以前讀一篇文章的時(shí)候都是快速瀏覽,一掃而過根本就沒有認(rèn)真閱讀,有時(shí)間讓自己靜下心來讀一篇文章收獲還是漫漫的,再次感謝原作者
https://www.cnblogs.com/ldq2016/p/5407061.html

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

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