为ViewGroup添加入场动画,LayoutAnimation使用概述

本篇文章来一点好玩的效果。还记得之前的视图动画效果吗?之前我们控制的效果,都是针对单个视图,如果想要对一组视图使用相同的动画效果,这个时候,就需要使用到LayoutAnimationController了。

LayoutAnimationController介绍:

Android Developer LayoutAnimationController docment

  • LayoutAnimationController用于为一个layout里面的控件,或者是一个ViewGroup里面的控件设置动画效果(即整个布局)
  • 每一个控件都有相同的动画效果
  • 这些控件的动画效果可在不同的时间显示出来

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

可以看到动画的执行顺序是顺序执行的,ViewGroupRecyclerView中,都是顺序执行的,但是如果现在是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);
        }
    }
}

使用上和之前使用没有任何区别。下面来看下效果。动画执行顺序还是区别很明显的。

你可能感兴趣的:(动画与过度,android,动画,android,java)