LayoutTransition 佈局容器動畫

首先,在佈局容器中添加屬性java

android:animateLayoutChanges=」true」android

 

LayoutTransition

該類用於當前佈局容器中有View添加,刪除,隱藏,顯示的時候定義佈局容器自身的動畫和View的動畫。也就是說當一個LinerLayout中隱藏一個view的時候,咱們能夠自定義 整個LinerLayout容器由於隱藏了view而改變的動畫,同時還能夠自定義被隱藏的view本身消失時候的動畫。你能夠先new一個LayoutTransition對象,經過setLayoutTransition()方法將對象設置進一個佈局容器ViewGroup中去。代碼以下:app

private LinearLayout container;
private LayoutTransition mTransitioner;
/**
* 初始化容器動畫
*/
private void initTransition() {
mTransitioner = new LayoutTransition();
container.setLayoutTransition(mTransitioner);
}

 

LayoutTransition類定義了以下幾種佈局容器動畫類型。dom

APPEARING :當view出現或者添加的時候,view出現的動畫 DISAPPEARING :當view消失或者隱藏的時候,view消失的動畫 CHANGE_APPEARING :當添加view致使佈局容器改變的時候,整個佈局容器的動畫 CHANGE_DISAPPEARING :當刪除或者隱藏view致使佈局容器改變的時候,整個佈局容器的動畫ide

你能夠自定義這些動畫,經過setAnimator() 方法把它們設置進一個 LayoutTransition 對象中去。佈局

LayoutTransition的用法

APPEARING–view出現的動畫

/**
* view出現時 view自身的動畫效果
*/

ObjectAnimator animator1 = ObjectAnimator.ofFloat(null, "rotationY", 0F, 90F, 0F);

mTransitioner.setAnimator(LayoutTransition.APPEARING, animator1);

定義一個旋轉的屬性動畫,這裏將動畫對象置空,由於系統內部會將添加的view設置爲動畫對象。而後調用setAnimator()方法將動畫設置進LayoutTransition對象mTransitioner中。動畫

完整代碼:this

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.Keyframe;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;

/**
 * Description:佈局動畫Demo
 * User: xjp
 * Date: 2015/5/22
 * Time: 15:06
 */

public class LayoutAnimationActivity extends Activity {


    private int i = 0;
    private LinearLayout container;
    private LayoutTransition mTransitioner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_layout_animation);

        container = (LinearLayout) findViewById(R.id.parent);

        initTransition();
        setTransition();
    }

    /**
     * 初始化容器動畫
     */
    private void initTransition() {
        mTransitioner = new LayoutTransition();
        container.setLayoutTransition(mTransitioner);
    }


    private void setTransition() {
        /**
         * view出現時 view自身的動畫效果
         */
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(null, "rotationY", 90F, 0F).
                setDuration(mTransitioner.getDuration(LayoutTransition.APPEARING));
        mTransitioner.setAnimator(LayoutTransition.APPEARING, animator1);

        /**
         * view 消失時,view自身的動畫效果
         */
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(null, "rotationX", 0F, 90F, 0F).
                setDuration(mTransitioner.getDuration(LayoutTransition.DISAPPEARING));
        mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animator2);

        /**
         * view 動畫改變時,佈局中的每一個子view動畫的時間間隔
         */
        mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);
        mTransitioner.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 30);


        /**
         * 爲何這裏要這麼寫?具體我也不清楚,ViewGroup源碼裏面是這麼寫的,我只是模仿而已
         * 不這麼寫貌似就沒有動畫效果了,因此你懂的!
         */
        PropertyValuesHolder pvhLeft =
                PropertyValuesHolder.ofInt("left", 0, 1);
        PropertyValuesHolder pvhTop =
                PropertyValuesHolder.ofInt("top", 0, 1);
        PropertyValuesHolder pvhRight =
                PropertyValuesHolder.ofInt("right", 0, 1);
        PropertyValuesHolder pvhBottom =
                PropertyValuesHolder.ofInt("bottom", 0, 1);


        /**
         * view出現時,致使整個佈局改變的動畫
         */
        PropertyValuesHolder animator3 = PropertyValuesHolder.ofFloat("scaleX", 1F, 2F, 1F);
        final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder(
                this, pvhLeft, pvhTop, pvhRight, pvhBottom, animator3).
                setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_APPEARING));
        changeIn.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                View view = (View) ((ObjectAnimator) animation).getTarget();
                view.setScaleX(1.0f);
            }
        });
        mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn);


        /**
         * view消失,致使整個佈局改變時的動畫
         */
        Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
        Keyframe kf1 = Keyframe.ofFloat(.5f, 2f);
        Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
        PropertyValuesHolder pvhRotation =
                PropertyValuesHolder.ofKeyframe("scaleX", kf0, kf1, kf2);
        final ObjectAnimator changeOut = ObjectAnimator.ofPropertyValuesHolder(
                this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhRotation).
                setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_DISAPPEARING));
        changeOut.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                View view = (View) ((ObjectAnimator) animation).getTarget();
                view.setScaleX(1.0f);
            }
        });
        mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut);
    }


    public void buttonClick(View view) {
        addButtonView();
    }

    public void buttonClick1(View view) {
        removeButtonView();
    }

    private void addButtonView() {
        i++;
        Button button = new Button(this);
        button.setText("button" + i);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        container.addView(button, Math.min(1, container.getChildCount()), params);
    }

    private void removeButtonView() {
        if (i > 0)
            container.removeViewAt(0);
    }
}

 

實現這種效果只須要在佈局中添加android:layoutAnimation=」@anim/layout」屬性就行了。接下來咱們來看看layout.xml動畫怎麼實現的?在res/anim目錄下新建layout.xml文件,代碼以下:spa

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/left"
    android:animationOrder="normal"
    android:delay="30%"></layoutAnimation>

android:delay 子類動畫時間間隔 (延遲) 70% 也能夠是一個浮點數 如「1.2」等 
android:animationOrder=」random」 子類的顯示方式 random表示隨機 
android:animationOrder 的取值有 
normal 0 默認 
reverse 1 倒序 
random 2 隨機 
android:animation=」@anim/left」 表示孩子顯示時的具體動畫是什麼代碼
在res/anim目錄下新建left.xml文件,碼以下:.net

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fromXDelta="100%"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="0" />
    <alpha
        android:duration="500"
        android:fromAlpha="0"
        android:toAlpha="1" />
</set>

固然咱們也能夠在代碼中實現這種動畫效果

private void initAinm() {
        //經過加載XML動畫設置文件來建立一個Animation對象;
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.left);
        //獲得一個LayoutAnimationController對象;
        LayoutAnimationController lac = new LayoutAnimationController(animation);
        //設置控件顯示的順序;
        lac.setOrder(LayoutAnimationController.ORDER_REVERSE);
        //設置控件顯示間隔時間;
        lac.setDelay(1);
        //爲ListView設置LayoutAnimationController屬性;
        listView.setLayoutAnimation(lac);
    }

經過AnimationUtils.loadAnimation加載item的動畫來得到一個Animation對象,而後將Animation對象設置到LayoutAnimationController中來得到LayoutAnimationController對象,配置LayoutAnimationController對象的一些屬性。最後將LayoutAnimationController對象設置到ListView中。

注意

layoutAnimation動畫不單單限於ListView,GridView中,也可用於一切ViewGroup中。具體怎麼用就看項目需求了。

總結

Android屬性動畫至此就基本介紹完畢了。其中基本的動畫使用和實例也貼出來了,基本能知足平常開發需求,固然有更炫的動畫時能夠根據這些基礎去實現。這麼說,之後均可以不用補間動畫了?貌似屬性動畫更加合理,由於這種動畫改變的是屬性而不單單是位置。

相關文章
相關標籤/搜索