Android動畫學習筆記大集合

  其實動畫這個東西我已經瞭解過很長一段時間了,但是一直沒系統的整理過。關於android中的各種動畫雖然都會用,但總怕自己會慢慢遺忘。這回看了幾篇動畫分析的文章,自己也學到了一些東西,在此就梳理一下。

參考博文如下,感謝大神們的分享:

http://www.open-open.com/lib/view/open1329994048671.html

http://www.tuicool.com/articles/yeM3my

http://blog.csdn.net/singwhatiwanna/article/details/17841165

http://blog.csdn.net/lmj623565791/article/details/38067475

http://blog.csdn.net/lmj623565791/article/details/38092093

 

注意:所有view的動畫就是被限制在它的父控件中的,即使你做了view的移動,它也不可能顯示在父控件的外邊。也就是說父控件是一個舞臺,演員可以在舞臺上到處走動,但如果超過了舞臺,那麼觀衆就看不到了。

 

一、View Animation(Tween Animation)

View Animation(Tween Animation):也可稱爲補間動畫(Tween Animation),給出兩個關鍵幀,通過一些算法將給定屬性值在給定的時間內在兩個關鍵幀間漸變。

View animation只能應用於View對象,而且只支持一部分屬性,如支持縮放旋轉而不支持背景顏色的改變。

對於View animation,它只是改變了View對象繪製的位置,注意這是“繪製”,而不是實際的位置。比如你讓一個button變成它的兩倍大小,但是它能接受你點擊的區域還是原來的button區域,沒有做任何改變。

View Animation支持設定多種動畫樣式,也可以設定這些動畫的執行順序,支持通過xml和代碼兩種方式來設置動畫效果。

動畫舉例

【 By XML 】

複製代碼
<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:shareInterpolator="true"
    android:startOffset="50">  

    <alpha
        android:duration="200"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>
複製代碼
     Animation aimation = AnimationUtils.loadAnimation(this, R.anim.anim);
        final ImageView imageView = (ImageView) findViewById(R.id.imageView_id);
        imageView.startAnimation(aimation);

可以對動畫添加監聽器

複製代碼
    aimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                animation = null;

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
複製代碼

如果你是用AnimationSet設置動畫的話,animationSet也是繼承自Animation,所以也有setAnimationListener的方法

詳細代碼可以參考:http://www.cnblogs.com/tianzhijiexian/p/3983616.html

 

【 By JAVA 】

通過java代碼來做的,可以參考這篇文章。其實也就是各種類繼承Animation,然後有自己獨特的方法,也可以通過AnimationSet進行各種設置。

http://www.cnblogs.com/tianzhijiexian/p/3981241.html

 

二、Drawable Animation(Frame Animation)

Drawable Animation(Frame Animation):幀動畫,就像GIF圖片,通過一系列Drawable依次顯示來模擬動畫的效果。在XML中的定義方式如下:

複製代碼
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />     <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />     <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>
複製代碼

必須以<animation-list>爲根元素,以<item>表示要輪換顯示的圖片,duration屬性表示各項顯示的時間。XML文件要放在/res/drawable/目錄下。

複製代碼
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
setContentView(R.layout.main); imageView
= (ImageView) findViewById(R.id.imageView1); imageView.setBackgroundResource(R.drawable.drawable_anim); AnimationDrawable anim = (AnimationDrawable) imageView.getBackground(); } public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { anim.stop(); anim.start(); return true; } return super.onTouchEvent(event); }
複製代碼

 我在實驗中遇到兩點問題:

  • 要在代碼中調用Imageview的setBackgroundResource方法,如果直接在XML佈局文件中設置其src屬性當觸發動畫時會FC。
  • 在動畫start()之前要先stop(),不然在第一次動畫之後會停在最後一幀,這樣動畫就只會觸發一次。
  • 最後一點是SDK中提到的,不要在onCreate中調用start,因爲AnimationDrawable還沒有完全跟Window相關聯,如果想要界面顯示時就開始動畫的話,可以在onWindowFoucsChanged()中調用start()。

 

三、Property Animation

 屬性動畫,這個是在Android 3.0中才引進的,它更改的是對象的實際屬性,如Button的縮放,Button的位置與大小屬性值都改變了。而且Property Animation不止可以應用於View,還可以應用於任何對象(Object)。Property Animation只是表示一個值在一段時間內的改變,當值改變時要做什麼事情完全是你自己決定的。

在Property Animation中,可以對動畫應用以下屬性:

  • Duration:動畫的持續時間,單位ms
  • TimeInterpolation:屬性值的計算方式,如先快後慢,是一個接口。用來設置插值器
  • TypeEvaluator:根據屬性的開始、結束值與TimeInterpolation計算出的因子計算出“當前”時間的屬性值,這個值可以在AnimationUpdate中得到
  • Repeat Country and behavoir:重複次數與方式,如播放3次、5次、無限循環,可以此動畫一直重複,或播放完時再反向播放
  • Animation sets:動畫集合,即可以同時對一個對象應用幾個動畫,這些動畫可以同時播放也可以對不同動畫設置不同開始偏移
  • Frame refreash delay:多少時間刷新一次,即每隔多少時間計算一次屬性值,默認爲10ms,最終刷新時間還受系統進程調度與硬件的影響

 

 

四、ValueAnimator

ValueAnimator包含Property Animation動畫的所有核心功能,如動畫時間,開始、結束屬性值,相應時間屬性值計算方法等。它其實就是一個計算器,並不能實際執行動畫效果。它可以計算出動畫要執行的時間,每隔幾毫秒刷新一次等等,但具體如何執行動畫,它是不管的。你需要在ValueAnimator的ValueAnimator.onUpdateListener監聽器中進行設置。

這裏給ValueAnimator對象設置了一個值,因爲是一個值,所以會默認爲是最終的結果值,動畫默認從當前的值到你設定的這個值。如果你設定兩個值,那麼它就意味着是從第一個值到另一個值進行動畫。

複製代碼
     // set one value,it is final value.
        // If you set two values in it.It means animation will start from first value to Second value.
        ValueAnimator animator = ValueAnimator.ofFloat(1f);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                
            }
        });
    animator.start();
複製代碼

這個AnimationUpdateListener將會在動畫執行過程中觸發。如果你沒在這裏做任何處理,那麼即使是執行了(start())也不會有任何動畫的。

實際運用——自由落體 & 拋物線

 

如果我希望小球拋物線運動【實現拋物線的效果,水平方向100px/s,垂直方向加速度200px/s*s 】,分析一下,貌似只和時間有關係,但是根據時間的變化,橫向和縱向的移動速率是不同的,我們該咋實現呢?此時就要重寫TypeValue的時候了,因爲我們在時間變化的同時,需要返回給對象兩個值,x當前位置,y當前位置。

複製代碼
/**
     * 拋物線
     * @param view
     */
    public void paowuxian(View view)
    {

        ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setDuration(3000);
        valueAnimator.setObjectValues(new PointF(0, 0));
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setEvaluator(new TypeEvaluator<PointF>()
        {
            // fraction = t / duration
            @Override
            public PointF evaluate(float fraction, PointF startValue,
                    PointF endValue)
            {
                Log.e(TAG, fraction * 3 + "");
                // x方向200px/s ,則y方向0.5 * 10 * t
                PointF point = new PointF();
                point.x = 200 * fraction * 3;
                point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
                return point;
            }
        });

        valueAnimator.start();
        valueAnimator.addUpdateListener(new AnimatorUpdateListener()
        {
            @Override
            public void onAnimationUpdate(ValueAnimator animation)
            {
                PointF point = (PointF) animation.getAnimatedValue();
                mBlueBall.setX(point.x);
                mBlueBall.setY(point.y);

            }
        });
    }
複製代碼

可以看到,因爲ofInt,ofFloat等無法使用,我們自定義了一個TypeValue,每次根據當前時間返回一個PointF對象,(PointF和Point的區別就是x,y的單位一個是float,一個是int;RectF,Rect也是)PointF中包含了x、y的當前位置,然後我們在監聽器中獲取,動態設置屬性。

 

五、ObjectAnimator

實際應用中一般都會用ObjectAnimator來產生某一對象的動畫,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,應該滿足以下條件:

  • 對象應該有一個setter函數:set<PropertyName>(駝峯命名法)
  • 如上面的例子中,像ofFloat之類的工場方法,第一個參數爲對象名,第二個爲屬性名,後面的參數爲可變參數,如果values…參數只設置了一個值的話,那麼會假定爲目的值,屬性值的變化範圍爲當前值到目的值,爲了獲得當前值,該對象要有相應屬性的getter方法:get<PropertyName>
  • 如果有getter方法,其應返回值類型應與相應的setter方法的參數類型一致。

  如果上述條件不滿足,則不能用ObjectAnimator,應用ValueAnimator代替。

下面是將imageview進行透明度漸變的例子。

    ObjectAnimator oa=ObjectAnimator.ofFloat(imageview, "alpha", 0f, 1f);
    oa.setDuration(3000);
    oa.start();

根據應用動畫的對象或屬性的不同,可能需要在onAnimationUpdate函數中調用invalidate()函數刷新視圖。

 

下面分析下屬性動畫的原理:

屬性動畫要求動畫作用的對象提供該屬性的get和set方法,屬性動畫根據你傳遞的該熟悉的初始值和最終值,以動畫的效果多次去調用set方法,每次傳遞給set方法的值都不一樣,確切來說是隨着時間的推移,所傳遞的值越來越接近最終值。總結一下,你對object的屬性xxx做動畫,如果想讓動畫生效,要同時滿足兩個條件:

  • object必須要提供setXxx方法,如果動畫的時候沒有傳遞初始值,那麼還要提供getXxx方法,因爲系統要去拿xxx屬性的初始值(如果這條不滿足,程序直接Crash)
  • object的setXxx對屬性xxx所做的改變必須能夠通過某種方法反映出來,比如會帶來ui的改變啥的(如果這條不滿足,動畫無效果但不會Crash)

以上條件缺一不可

 那麼如果我們的object沒辦法滿足這個條件呢?比如button的setWidth方法僅僅是設置它的最小寬度(minWidth),對於實際寬度不會產生任何影響。如果讓它實際改變就需要用

btn.getLayoutParams().width = xxx;

來設置,但這種通過方法來獲得public值的方法又不適合ObjecAnimator的應用場景,改怎麼辦呢?

針對上述問題,Google告訴我們有3中解決方法:

1. 給你的對象加上get和set方法,如果你有權限的話

對於View我們沒權限給其添加各種屬性,所以這種方法僅僅適合於自己定義的Object對象

2. 用一個類來包裝原始對象,間接爲其提供get和set方法

這個方法很好,你可以寫一個類繼承那個Object對象,在子類中添加各種set、get方法,更好的辦法是寫一個包裝類,傳入一個object對象,然後給其添加各種方法。

複製代碼
    private void performAnimate() {
        ViewWrapper wrapper = new ViewWrapper(mButton);
        ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();
    }

    @Override
    public void onClick(View v) {
        if (v == mButton) {
            performAnimate();
        }
    }

    private static class ViewWrapper {
        private View mTarget;

        public ViewWrapper(View target) {
            mTarget = target;
        }

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

        public void setWidth(int width) {
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout();
        }
    }
複製代碼

上面類中ViewWrapper這個內部類就是一個包裝類,它的構造函數傳入一個View對象,然後提供了set和get方法,這樣我們就可以對它進行動畫的操作了

3. 採用ValueAnimator,監聽動畫過程,自己實現屬性的改變

 這個方法就有些彆扭了,但擴展性是最強的。ValueAnimator我們在上面已經介紹過了,下面是在動畫執行過程中能的得到的東西。

複製代碼
ValueAnimator animator = ValueAnimator.ofFloat(1, 1);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer currentValue = (Integer)animation.getAnimatedValue(); // current Value(0~100)

                float fraction = valueAnimator.getAnimatedFraction(); // progress of animation
            }
        });
複製代碼

getAnimatedFraction() 這個可以得到當前動畫的進度,得到的是浮點型數據很有用。api12中加入的,感覺比getAnimationValue有用

getAnimatedValue(String propertyName) 得到某個特定屬性當前的值,這個可用性就很高了。如果有特殊要求可以用它

其餘的屬性都在下面了,看名字就知道是什麼意思啦~

 

實際運用

這個例子是將一個view進行移動和拉伸的動畫。涉及了多個屬性,當你要讓view選裝或者是移動的時候,請務必設定PivotX,PivotY來指定座標,如果不設定的話,移動和選擇默認的中心點都是Object的中心

複製代碼
public void startViewSimpleAnim(final View fromView,Rect finalBounds,int 
            startOffsetY,int finalOffsetY, float startAlpha, float finalAlpha) {
        Rect startBounds  = new Rect();
        startBounds.set(Position.getGlobalVisibleRect(fromView));
        //設置偏移量
        startBounds.offset(0, -startOffsetY);
        finalBounds.offset(0, -finalOffsetY);
        //設定拉伸或者旋轉動畫的中心位置,這裏是相對於自身左上角
        fromView.setPivotX(0f);
        fromView.setPivotY(0f);
        //計算拉伸比例
        float scaleX = (float)finalBounds.width() / startBounds.width();
        float scaleY = (float)finalBounds.height() / startBounds.height();
        
        AnimatorSet set = new AnimatorSet();
        ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(fromView, "alpha", startAlpha, finalAlpha);
        ObjectAnimator xAnim = ObjectAnimator.ofFloat(fromView, "x", startBounds.left, finalBounds.left);
        ObjectAnimator yAnim = ObjectAnimator.ofFloat(fromView, "y", startBounds.top, finalBounds.top);
        ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(fromView, View.SCALE_X, 1f, scaleX);
        ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(fromView, View.SCALE_Y,1f, scaleY);
        
        set.play(alphaAnim).with(xAnim).with(yAnim).with(scaleXAnim).with(scaleYAnim);
        
        set.setStartDelay(mStartDelay);
        set.setDuration(mAnimTime);
        set.setInterpolator(mInterpolator);
        set.addListener(new AnimListener(fromView,null));

        set.start();
    }
複製代碼

如果你操作對象的該屬性方法裏面,比如上例的setRotationX如果內部沒有調用view的重繪,則你需要自己按照下面方式手動調用。

複製代碼
anim.addUpdateListener(new AnimatorUpdateListener()
        {
            @Override
            public void onAnimationUpdate(ValueAnimator animation)
            {
//                view.postInvalidate();
//                view.invalidate();
            }
        });
複製代碼

 

用xml文件來創建屬性動畫

大家肯定都清楚,View Animator 、Drawable Animator都可以在anim文件夾下創建動畫,然後在程序中使用,甚至在Theme中設置爲屬性值。當然了,屬性動畫其實也可以在文件中聲明。

 

首先在res下建立animator文件夾,然後建立res/animator/scalex.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>
複製代碼

然後通過動畫工具類就可以加載xml中的動畫文件了

 AnimatorInflater.loadAnimator(this, R.anim.anim);

複製代碼
public void scaleX(View view)
    {
        // 加載動畫
        Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);
        anim.setTarget(mMv);
        anim.start();
    }
複製代碼

 

縱向與橫向同時縮放

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together" >

    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleX"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>
    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleY"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>

</set>
複製代碼

使用set標籤,有一個orderring屬性設置爲together,【還有另一個值:sequentially(表示一個接一個執行)】

 

六、通過AnimatorSet來控制多個動畫

AnimatorSet和AnimationSet類似,可以操作多個動畫屬性。AnimationSet提供了一個把多個動畫組合成一個組合的機制,並可設置組中動畫的時序關係,如同時播放,順序播放等。

例子01:

複製代碼
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(anim1).before(anim2);
bouncer.play(anim2).with(anim3);
bouncer.play(anim2).with(anim4)
bouncer.play(anim5).after(amin2);
animatorSet.start();
複製代碼
  1. 播放anim1;
  2. 同時播放anim2,anim3,anim4;
  3. 播放anim5。

例子02:

animSet.playTogether(anim1, anim2);  
animSet.start();  

使用playTogether兩個動畫同時執行,當然還有playSequentially依次執行

例子03:

複製代碼
     /** 
         * anim1,anim2,anim3同時執行 
         * anim4接着執行 
         */  
        AnimatorSet animSet = new AnimatorSet();  
        animSet.play(anim1).with(anim2);  
        animSet.play(anim2).with(anim3);  
        animSet.play(anim4).after(anim3);  
        animSet.setDuration(1000);  
        animSet.start(); 
複製代碼

如果我們有一堆動畫,如何使用代碼控制順序,比如1,2同時;3在2後面;4在1之前

注意animSet.play().with();也是支持鏈式編程的,但是不要想太多。

比如:animSet.play(anim1).with(anim2).before(anim3).before(anim5);

這樣是不行的,系統不會根據你寫的這一長串來決定先後的順序,所以麻煩你按照上面例子的寫法,多寫幾行

 

七、ViewPropertyAnimator

 如果需要對一個View的多個屬性進行動畫可以用ViewPropertyAnimator類,該類對多屬性動畫進行了優化,會合並一些invalidate()來減少刷新視圖,該類在3.1中引入。

例子01:

以下兩段代碼實現同樣的效果

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
myView.animate().x(50f).y(100f);

例子02:

在SDK12的時候,給View添加了animate方法,更加方便的實現動畫效果。

 btn.animate().x(200).y(200).alpha(0f); 就可以實現動畫效果了~

例子03:

簡單的使用mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000).start()就能實現動畫~~不過需要SDK11,此後在SDK12,SDK16又分別添加了withStartAction和withEndAction用於在動畫前,和動畫後執行一些操作。當然也可以.setListener(listener)等操作。

複製代碼
package com.example.zhy_property_animation;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

public class ViewAnimateActivity extends Activity
{
    protected static final String TAG = "ViewAnimateActivity";

    private ImageView mBlueBall;
    private float mScreenHeight;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.view_animator);

        DisplayMetrics outMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
        mScreenHeight = outMetrics.heightPixels;
        mBlueBall = (ImageView) findViewById(R.id.id_ball);

    }

    public void viewAnim(View view)
    {
        // need API12
        mBlueBall.animate()//
                .alpha(0)//
                .y(mScreenHeight / 2).setDuration(1000)
                // need API 12
                .withStartAction(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        Log.e(TAG, "START");
                    }
                    // need API 16
                }).withEndAction(new Runnable()
                {

                    @Override
                    public void run()
                    {
                        Log.e(TAG, "END");
                        runOnUiThread(new Runnable()
                        {
                            @Override
                            public void run()
                            {
                                mBlueBall.setY(0);
                                mBlueBall.setAlpha(1.0f);
                            }
                        });
                    }
                }).start();
    }                                                                                                                                                  }
複製代碼

 

八、TypeEvalutors<T>

根據屬性的開始、結束值與TimeInterpolation計算出的因子計算出當前時間的屬性值,Android提供了以下幾個evalutor:

  • IntEvaluator:屬性的值類型爲int;
  • FloatEvaluator:屬性的值類型爲float;
  • ArgbEvaluator:屬性的值類型爲十六進制顏色值;
  • TypeEvaluator:一個接口,可以通過實現該接口自定義Evaluator。

  自定義TypeEvalutor很簡單,只需要實現一個方法,如FloatEvalutor的定義:

複製代碼
public class FloatEvaluator implements TypeEvaluator {
    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}
複製代碼

根據動畫執行的時間跟應用的Interplator,會計算出一個0~1之間的因子,即evalute函數中的fraction參數,通過上述FloatEvaluator應該很好看出其意思。

 

九、當Layout改變時應用動畫

ViewGroup中的子元素可以通過setVisibility使其Visible、Invisible或Gone,當有子元素可見性改變時,可以向其應用動畫。

通過LayoutTransition類的常量(第一個參數)可以區分動畫的類型,第二個參數爲Animator。

  • APPEARING        當一個元素變爲Visible時對其應用的動畫
  • CHANGE_APPEARING   當一個元素變爲Visible時,因系統要重新佈局有一些元素需要移動,這些要移動的元素應用的動畫
  • DISAPPEARING      當一個元素變爲InVisible時對其應用的動畫
  • CHANGE_DISAPPEARING 當一個元素變爲Gone時,因系統要重新佈局有一些元素需要移動,這些要移動的元素應用的動畫 disappearing from the container.
mTransition.setAnimator(LayoutTransition.DISAPPEARING, customDisappearingAnim);

更多的解釋

  • 過渡的類型一共有四種:
  • LayoutTransition.APPEARING 當一個View在ViewGroup中出現時,對此View設置的動畫
  • LayoutTransition.CHANGE_APPEARING 當一個View在ViewGroup中出現時,對此View對其他View位置造成影響,對其他View設置的動畫
  • LayoutTransition.DISAPPEARING  當一個View在ViewGroup中消失時,對此View設置的動畫
  • LayoutTransition.CHANGE_DISAPPEARING 當一個View在ViewGroup中消失時,對此View對其他View位置造成影響,對其他View設置的動畫
  • LayoutTransition.CHANGE 不是由於View出現或消失造成對其他View位置造成影響,然後對其他View設置的動畫。
  • 注意動畫到底設置在誰身上,此View還是其他View。

詳細的例子,請參考:http://blog.csdn.net/lmj623565791/article/details/38092093

 

參考博文如下:

http://www.open-open.com/lib/view/open1329994048671.html

http://www.tuicool.com/articles/yeM3my

http://blog.csdn.net/singwhatiwanna/article/details/17841165

http://blog.csdn.net/lmj623565791/article/details/38067475

http://blog.csdn.net/lmj623565791/article/details/38092093

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章