首先,在布局容器中添加属性java
android:animateLayoutChanges=”true”android
该类用于当前布局容器中有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 对象中去。布局
/** * 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属性动画至此就基本介绍完毕了。其中基本的动画使用和实例也贴出来了,基本能知足平常开发需求,固然有更炫的动画时能够根据这些基础去实现。这么说,之后均可以不用补间动画了?貌似属性动画更加合理,由于这种动画改变的是属性而不单单是位置。