Android动画之布局动画
布局动画是针对于ViewGroup使用的,我们直接上效果,通过效果分析进行实现。

首先我们分析一下效果图,总共可分为两种,
- 在我们的界面初始化显示时,会垂直显示一条垂直的按钮,他们会从右边按照顺序飞入。
- 当我们向这个垂直的按钮列表添加和移除按钮时,添加或删除的按钮有一个进入和飞出的动画,他所影响的其他按钮也会有一个过渡动画。
这两中效果分别使用了Android中的两个类,LayoutAnimationController和LayoutTransition。
如果对于动画不是很熟练的同学可以看我之前的博客Android动画之视图动画和属性动画
LayoutAniamtionContrller
该动画主要用于针对于一个ViewGroup初始化时对于其下子控件的动画操作。针对于上面的效果,我们的实现方式如下:
首先,可以看到我们的控件是从右边进入,逐渐显现,所以定义如下动画
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500"> <translate android:fromXDelta="100%" android:fromYDelta="0" android:toXDelta="0" android:toYDelta="0"/> <alpha android:fromAlpha="0" android:toAlpha="1"/> </set>
在代码中,加载动画,并通过LayoutAnimationController设置到LinearLayout上。
//通过加载XML动画设置文件来创建一个Animation对象; Animation animation= AnimationUtils.loadAnimation(this, R.anim.listview_item_anim); //得到一个LayoutAnimationController对象; LayoutAnimationController controller = new LayoutAnimationController(animation); //设置控件显示的顺序; controller.setOrder(LayoutAnimationController.ORDER_NORMAL); //设置控件显示间隔时间; controller.setDelay(0.3f); //为ListView设置LayoutAnimationController属性; mParent.setLayoutAnimation(controller);
注释很清楚,唯一要解释的只有两点:
子控件显示顺序可取值
ORDER_NORMAL:正常顺序,及按照从上往下开始执行。ORDER_REVERSE:倒序。从下往上。ORDER_RANDOM:随机。间隔时间,可设置的值0.0~1.0(百分比值)。及上一个控件显示到多少是下一个控件开始执行动画。
因为其只是在控件初始化时调用,并且是对控件整体的子控件加载一个按照固定顺序显示的动画。我们可以调用ViewGroup.startLayoutAnimation()让其重新显示一遍。
LayoutTransition
对于一个LinearLayout,在xml中添加android:animateLayoutChanges="true"或者在java代码中添加代码
LayoutTransition mTransition = new LayoutTransition(); mParent.setLayoutTransition(mTransition);
LayoutTransition有默认的动画效果。
此时,我们如果在添加子控件或删除子控件,就有了动画效果。
当然,我们肯定要懂得如何自定义动画效果。看一下LayoutTransition的文档,可以看到有如下方法
public void setAnimator(int transitionType, Animator animator)
他的注释如下
@param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
{@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING},
which determines theanimation whose animator is being set.
@param animator The animation being assigned. A value of null means that no
animation will be run for the specified transitionType.第一个参数,我们要设置动画的目标,类型。第二个参数表示要设置的动画。
类型中可以取四个字段,这四个字段很重要。我们看一下他们的含义
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 mTransition = new LayoutTransition();
mParent.setLayoutTransition(mTransition); //view 进入
ObjectAnimator animator1 = ObjectAnimator.ofFloat(null, "rotationY", -90f, 0f)
.setDuration(mTransition.getDuration(LayoutTransition.APPEARING));
animator1.setInterpolator(new LinearInterpolator());
mTransition.setAnimator(LayoutTransition.APPEARING, animator1); //view 退出
PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);
PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofFloat("translationX", 0f, 1000f);
ObjectAnimator animator2 = ObjectAnimator.ofPropertyValuesHolder(new Object(), propertyValuesHolder, propertyValuesHolder1);
animator2.setDuration(mTransition.getDuration(LayoutTransition.DISAPPEARING));//
ObjectAnimator animator2 = ObjectAnimator.ofFloat(null,"translationX",0f,1000f).setDuration(1000);
mTransition.setAnimator(LayoutTransition.DISAPPEARING, animator2); //控件进入对其他控件的影响
// google 原生的写法, 不加会出错
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);
PropertyValuesHolder pvhScrollX = PropertyValuesHolder.ofInt("scrollX", 0, 1);
PropertyValuesHolder pvhScrollY = PropertyValuesHolder.ofInt("scrollY", 0, 1); //自定义的动画
PropertyValuesHolder pvhChangeAppearing = PropertyValuesHolder.ofFloat("scaleX", 1f, 2f, 1f);
ObjectAnimator animator3 = ObjectAnimator.ofPropertyValuesHolder(this, pvhLeft, pvhTop, pvhRight, pvhBottom,
pvhScrollX, pvhScrollY, pvhChangeAppearing);
mTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, animator3);
//如果当前动画没有结束,如果有新的View加入,会导致当前动画取消,并进行下一次动画,所以需要添加监听
animator3.addListener(new AnimatorListenerAdapter() { @Override
public void onAnimationEnd(Animator animation) {
View target = (View) ((ObjectAnimator) animation).getTarget();
target.setScaleX(1f);
}
}); //控件消失对其他控件的影响,类似于上面的,偷懒了
mTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, animator3);如果了解属性动画的,这个地方没有什么难点,唯一需要注意的是,在控件进入或消失对其他控件的影响时,会出现一种情况,当我们连续点击添加控件时,其他控件的动画还没结束,会将动画停止到其执行状态,并执行下一次动画。例如控件放大到一半时,停止并执行下一次动画,那么初始值就是控件放大到一半的值了,那么肯定会出错。所以需要设置动画监听,当动画结束时,设置其缩放。及上述代码中这段代码
animator3.addListener(new AnimatorListenerAdapter() { @Override
public void onAnimationEnd(Animator animation) {
View target = (View) ((ObjectAnimator) animation).getTarget();
target.setScaleX(1f);
}
});源码已更新到github,在animationdemo文件中。
转载自:http://blog.csdn.net/lisdye2/article/details/51396371