Add layout animation to custom ViewGroup with Android animation effect
Foreword:
The previous articles have introduced tween animation, frame-by-frame animation, and attribute animation, most of which are animations implemented for View, so how to add animation to a ViewGroup? Today, combine custom ViewGroup to learn layout animation. This article will learn layout animation by animating a custom image selection control as an example.
Several other animation effects:
- Tween Animation of Android animation effects (tween animation)
- Frame Animation of Android animation effects (frame-by-frame animation)
- The beginning of Android animation effects Property Animation (property animation)
- Android animation effect of Property Animation advanced (property animation)
- Add layout animation to custom ViewGroup with Android animation effect
Customize a ViewGroup that displays multiple rows of images:
I will no longer explain custom controls here. If you want to know more, you can read the following articles
- Basic principles of Android custom controls (1)
- Custom attributes of Android custom controls (2)
- Custom Combination Controls for Android Custom Controls (3)
- Custom ViewGroup of Android Custom Control to Implement Tag Cloud (4)
Declare several property values:
<declare-styleable name="GridImageViewGroup"> <attr name="childVerticalSpace" format="dimension"/> <attr name="childHorizontalSpace" format="dimension"/> <attr name="columnNum" format="integer"/> </declare-styleable>
GridImageViewGroup.java code
Quoting in xml:
<com.whoislcj.animation.GridImageViewGroup android:id="@+id/image_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:animateLayoutChanges="true" lee:childHorizontalSpace="10dp" lee:childVerticalSpace="10dp" lee:columnNum="3"/>
Call in Activity:
private void initViews() { mImageViewGroup = (GridImageViewGroup) findViewById(R.id.image_layout); ImageView imageView = new ImageView(this); imageView.setImageResource(R.mipmap.add_image); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { addImageView(); } }); mImageViewGroup.addView(imageView); } public void addImageView() { final ImageView imageView = new ImageView(MainActivity4.this); imageView.setImageResource(R.mipmap.lottery); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mImageViewGroup.removeView(imageView); } }); mImageViewGroup.addView(imageView, 0); }
实现效果如下:
布局动画产生的背景:
凡事总要问个明白,为何要引入布局动画呢?其实通过上面的实现效果可以看出,在添加和删除图片时都显得很突兀,不知道该用什么语言形容了,总之就是感觉不舒服。其实我平时在开发中调用View.setVisibility()方法时也会有这种感受,这也是布局动画产生的一个背景吧。
布局动画:
布局动画是指ViewGroup在布局时产生的动画效果 。实现布局动画有如下几种方式
第一种方式:在xml中,对ViewGrope设置android:animateLayoutChanges="true"
属性:
<com.whoislcj.animation.GridImageViewGroup android:id="@+id/image_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:animateLayoutChanges="true" lee:childHorizontalSpace="10dp" lee:childVerticalSpace="10dp" lee:columnNum="3"/>
就这么简单的一句话实现的效果就可以实现了,看看效果如何
这种方式虽然简单但是实现的布局动画比较单一,下面看第二种方式。
第二种方式:LayoutTransition实现
LayoutTransition mLayoutTransition = new LayoutTransition(); //设置每个动画持续的时间 mLayoutTransition.setStagger(LayoutTransition.CHANGE_APPEARING, 50); mLayoutTransition.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 50); mLayoutTransition.setStagger(LayoutTransition.APPEARING, 50); mLayoutTransition.setStagger(LayoutTransition.DISAPPEARING, 50); PropertyValuesHolder appearingScaleX = PropertyValuesHolder.ofFloat("scaleX", 0.5f, 1.0f); PropertyValuesHolder appearingScaleY = PropertyValuesHolder.ofFloat("scaleY", 0.5f, 1.0f); PropertyValuesHolder appearingAlpha = PropertyValuesHolder.ofFloat("alpha", 0f, 1f); ObjectAnimator mAnimatorAppearing = ObjectAnimator.ofPropertyValuesHolder(this, appearingAlpha, appearingScaleX, appearingScaleY); //为LayoutTransition设置动画及动画类型 mLayoutTransition.setAnimator(LayoutTransition.APPEARING, mAnimatorAppearing); PropertyValuesHolder disappearingAlpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0f); PropertyValuesHolder disappearingRotationY = PropertyValuesHolder.ofFloat("rotationY", 0.0f, 90.0f); ObjectAnimator mAnimatorDisappearing = ObjectAnimator.ofPropertyValuesHolder(this, disappearingAlpha, disappearingRotationY); //为LayoutTransition设置动画及动画类型 mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mAnimatorDisappearing); ObjectAnimator mAnimatorChangeDisappearing = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f); //为LayoutTransition设置动画及动画类型 mLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mAnimatorChangeDisappearing); ObjectAnimator mAnimatorChangeAppearing = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f); //为LayoutTransition设置动画及动画类型 mLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, mAnimatorChangeAppearing); //为mImageViewGroup设置mLayoutTransition对象 mImageViewGroup.setLayoutTransition(mLayoutTransition);
上面通过自定义LayoutTransition 修改系统提高的默认动画效果,如果不需要自定义的动画效果的话,不调用mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mAnimatorDisappearing);就行了。
LayoutTransition 提供了以下几种过渡类型:
- APPEARING —— 元素在容器中显现时需要动画显示。
- CHANGE_APPEARING —— 由于容器中要显现一个新的元素,其它元素的变化需要动画显示。
- DISAPPEARING —— 元素在容器中消失时需要动画显示。
- CHANGE_DISAPPEARING —— 由于容器中某个元素要消失,其它元素的变化需要动画显示。
看下修改过的动画效果:
第三种方式:通过设置LayoutAnimation来实现布局动画
AlphaAnimation alphaAnimation = new AlphaAnimation(0f, 1f); alphaAnimation.setDuration(200); LayoutAnimationController animationController = new LayoutAnimationController(alphaAnimation, 0.5f); animationController.setOrder(LayoutAnimationController.ORDER_NORMAL); mImageViewGroup.setLayoutAnimation(animationController);
显示顺序有以下几种:
- ORDER_NORMAL;//顺序显示
- ORDER_REVERSE;//反显示
- ORDER_RANDOM//随机显示
也可以通过xml实现
<?xml version="1.0" encoding="utf-8"?> <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:delay="0.5" android:animationOrder="normal" android:animation="@anim/alpha" />
ViewGroup xml添加android:layoutAnimation属性
<com.whoislcj.animation.GridImageViewGroup android:id="@+id/image_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:layoutAnimation="@anim/layoutanimation" lee:childHorizontalSpace="10dp" lee:childVerticalSpace="10dp" lee:columnNum="3"/>