LayoutAnimation:顾名思义,组件内动画,这里参考apidemo中的例子做学习记录。
用处
viewgroup添加或者删除子view时的过度动画,避免子view显示的生硬。
用例参考
com.example.android.apis.animation.LayoutAnimations
用法及注意事项
-API10 以上使用
1.简单用法
使用系统默认的animation
<GridLayout
android:columnCount="4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/gridContainer"
android:animateLayoutChanges="true"
/>`
只要在你需要加上一个属性android:animateLayoutChanges="true",则此layout子view有变化时会有默认的过度动画,一般情况都可以满足我们的需求。
2.自定义animation:如果我们不想用系统默认的动画,那句需要自己来定义了。
- 首先介绍使用方法:
- 所有的动画属性都是针对LayoutTransition,llAnimContent.setLayoutTransition(transition)即可
LayoutTransition介绍:
-This class enables automatic animations on layout changes in ViewGroup objects. To enable transitions for a layout container, create a LayoutTransition object and set it on any ViewGroup by calling setLayoutTransition(LayoutTransition). This will cause default animations to run whenever items are added to or removed from that container. To specify custom animations, use the setAnimator() method.
详细了解:LayoutTransition四种场景
一共四种类型的动画
APPEARING ————- View本身的出现动画
CHANGE_APPEARING ———– 由于新增了其他View而需要改变位置的动画
DISAPPEARING ———– 消失动画
CHANGE_DISAPPEARING ———– 由于移除了其他View而需要改变位置的动画
例如:
ObjectAnimator customAppearingAnim = ObjectAnimator.ofFloat(null, "translationX", -700, 0). setDuration(transition.getDuration(LayoutTransition.APPEARING));
transition.setAnimator(LayoutTransition.APPEARING, customAppearingAnim);- 上段代码的就是设置了APPEARING—即layout addview时被添加view的动画,
这里我设置了从左到有淡入。 - 需要注意的是如果layout种本来就有其他的view 这时addview会出发CHANGE_APPEARING ,这里你只需要再定义相应的动画transition.setAnimator(LayoutTransition.CHANGE_APPEARING,anim)就OK了,当然,如果不想设置的话,也可以使用系统默认的偏移动画
- 上段代码的就是设置了APPEARING—即layout addview时被添加view的动画,
实战
- 现在我有一个LinnerLayout,我需要每次addview时,view从左边底部进 来,removeview时 列表顶部的view淡出,有点类似直播聊天室的例子。
- 针对LinnerLayout设置APPEARING ,DISAPPEARING 动画即可,随之发生的CHANGE_APPEARING ,CHANGE_DISAPPEARING 我们使用的默认的就好。
// add
transition = new LayoutTransition();
transition.setDuration(1000);
llAnimContent.setLayoutTransition(transition);
ObjectAnimator customAppearingAnim = ObjectAnimator.ofFloat(null, "translationX", -700, 0).
setDuration(transition.getDuration(LayoutTransition.APPEARING));
transition.setAnimator(LayoutTransition.APPEARING, customAppearingAnim);
// Removing
customDisappearingAnim = ObjectAnimator.ofFloat(null, "alpha", 1.0f, 0.0f).
setDuration(transition.getDuration(LayoutTransition.DISAPPEARING));
transition.setAnimator(LayoutTransition.DISAPPEARING, customDisappearingAnim);
- 这里我实际的需求是当itemview 充满布局后,每次add 先让顶部的view消失,再由底部addview进来,所以对APPEARING 做了监听,针对firstItemView 做特殊的淡出动画
这 customAppearingAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
if (llAnimContent.getChildCount() >= itemMaxCount) {
llAnimContent.post(new Runnable() {
@Override
public void run() {
//第一条淡出动画
View firstItemView = llAnimContent.getChildAt(0);
if(firstItemView == null){
return;
}
//这里为了排除外层layout remove动画对本身动画的影响 先清空 DISAPPEARING 动作的动画
transition.setAnimator(LayoutTransition.DISAPPEARING, null);
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(firstItemView, "alpha", 1.0f, 0.0f).
setDuration(transition.getDuration(LayoutTransition.DISAPPEARING));
alphaAnimator.start();
alphaAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
llAnimContent.removeViewAt(0);
transition.setAnimator(LayoutTransition.DISAPPEARING, customDisappearingAnim);
}
@Override
public void onAnimationCancel(Animator animation) {
transition.setAnimator(LayoutTransition.DISAPPEARING, customDisappearingAnim);
}
});
}
});
}
}
public void onAnimationEnd(Animator anim) {
Log.i(TAG, "APPEARING...childcount: " + llAnimContent.getChildCount());
View view = (View) ((ObjectAnimator) anim).getTarget();
view.setTranslationX(0);
}
});
- 另外有一点要写一下,APIDemos 提供的参考类中使用了
` PropertyValuesHolder pvhLeft =
PropertyValuesHolder.ofInt(“left”, 0, 1);
PropertyValuesHolder pvhTop =
PropertyValuesHolder.ofInt(“top”, 0, 1);
PropertyValuesHolder pvhRight =
PropertyValuesHolder.ofInt(“right”, 0, 1);
PropertyValuesHolder pvhBottom =- 注:PropertyValuesHolder 是一个animation集合类,用于将多种动画柔和在一起。PropertyValuesHolder
经个人测试,这四个属性括号内的值是像数(pix),动画执行的结果是改变自身getLeft,getRight,getTop,getBottom 的值,这几个属性容易改变view的大小,不推荐使用。