本篇文章来一点好玩的效果。还记得之前的视图动画效果吗?之前我们控制的效果,都是针对单个视图,如果想要对一组视图使用相同的动画效果,这个时候,就需要使用到LayoutAnimationController
了。
LayoutAnimationController介绍:
Android Developer LayoutAnimationController docment
LayoutAnimationController
的使用非常简单
xml直接使用
然后将定义好的动画配置到ViewGroup
的布局中即可。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llViewGroupContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/list_anim_layout"
android:background="@android:color/white"
android:orientation="vertical">
LinearLayout>
代码中配置使用
val layoutAnimationController =
LayoutAnimationController(LayoutAnimationHelper.getAnimationSetFromRight())
layoutAnimationController.delay= 0.1F
layoutAnimationController.order = LayoutAnimationController.ORDER_NORMAL
llViewGroupContainer.layoutAnimation = layoutAnimationController
llViewGroupContainer.scheduleLayoutAnimation()
/**
* 从右侧进入,并带有弹性的动画
*
* @return
*/
public static AnimationSet getAnimationSetFromRight() {
AnimationSet animationSet = new AnimationSet(true);
TranslateAnimation translateX1 = new TranslateAnimation(RELATIVE_TO_SELF, 1.0f, RELATIVE_TO_SELF, -0.1f,
RELATIVE_TO_SELF, 0, RELATIVE_TO_SELF, 0);
translateX1.setDuration(300);
translateX1.setInterpolator(new DecelerateInterpolator());
translateX1.setStartOffset(0);
TranslateAnimation translateX2 = new TranslateAnimation(RELATIVE_TO_SELF, -0.1f, RELATIVE_TO_SELF, 0.1f,
RELATIVE_TO_SELF, 0, RELATIVE_TO_SELF, 0);
translateX2.setStartOffset(300);
translateX2.setInterpolator(new DecelerateInterpolator());
translateX2.setDuration(50);
TranslateAnimation translateX3 = new TranslateAnimation(RELATIVE_TO_SELF, 0.1f, RELATIVE_TO_SELF, 0f,
RELATIVE_TO_SELF, 0, RELATIVE_TO_SELF, 0);
translateX3.setStartOffset(350);
translateX3.setInterpolator(new DecelerateInterpolator());
translateX3.setDuration(50);
AlphaAnimation alphaAnimation = new AlphaAnimation(0.5f, 1.0f);
alphaAnimation.setDuration(400);
alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.addAnimation(translateX1);
animationSet.addAnimation(translateX2);
animationSet.addAnimation(translateX3);
animationSet.addAnimation(alphaAnimation);
animationSet.setDuration(400);
return animationSet;
}
下面是效果
为了让大家看的时候更清晰效果,所以视频做了慢放处理,可以看到是有回弹会效果的,还是比较炫酷的。如果是recyclerView
,也可以使用LayoutAnimationController
来实现类似效果。
//为RecyclerView添加动画
val layoutAnimationController =
LayoutAnimationController(LayoutAnimationHelper.getAnimationSetFromRight())
layoutAnimationController.delay = 0.1F
layoutAnimationController.order = LayoutAnimationController.ORDER_NORMAL
rvContentList.layoutAnimation = layoutAnimationController
可以看到动画的执行顺序是顺序执行的,ViewGroup
和RecyclerView
中,都是顺序执行的,但是如果现在是GridView
或者RecylcerView#GridLayoutManager
方式,我们可能希望沿着对角线方向实现动画效果,而不是一个个来。则需要进行自定义动画的执行方向。LayoutAnimationController
动画执行方向修改也很简单,只需要重写ViewGroup#protected void attachLayoutAnimationParameters(View child, LayoutParams params, int index, int count)
方法即可。
下面是对于RecycleView#GridLayoutManager
实现对角线方向动画效果的代码
public class GridRecyclerView extends RecyclerView {
/** @see View#View(Context) */
public GridRecyclerView(Context context) { super(context); }
/** @see View#View(Context, AttributeSet) */
public GridRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); }
/** @see View#View(Context, AttributeSet, int) */
public GridRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }
@Override
protected void attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params,
int index, int count) {
final LayoutManager layoutManager = getLayoutManager();
if (getAdapter() != null && layoutManager instanceof GridLayoutManager){
GridLayoutAnimationController.AnimationParameters animationParams =
(GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;
if (animationParams == null) {
// If there are no animation parameters, create new once and attach them to
// the LayoutParams.
animationParams = new GridLayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
// Next we are updating the parameters
// Set the number of items in the RecyclerView and the index of this item
animationParams.count = count;
animationParams.index = index;
// Calculate the number of columns and rows in the grid
final int columns = ((GridLayoutManager) layoutManager).getSpanCount();
animationParams.columnsCount = columns;
animationParams.rowsCount = count / columns;
// Calculate the column/row position in the grid
final int invertedIndex = count - 1 - index;
animationParams.column = columns - 1 - (invertedIndex % columns);
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns;
} else {
// Proceed as normal if using another type of LayoutManager
super.attachLayoutAnimationParameters(child, params, index, count);
}
}
}
使用上和之前使用没有任何区别。下面来看下效果。动画执行顺序还是区别很明显的。