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属性动画至此就基本介绍完毕了。其中基本的动画使用和实例也贴出来了,基本能知足平常开发需求,固然有更炫的动画时能够根据这些基础去实现。这么说,之后均可以不用补间动画了?貌似属性动画更加合理,由于这种动画改变的是属性而不单单是位置。

相关文章
相关标签/搜索