Skip to content Skip to sidebar Skip to footer

How Do I Use A Gridlayoutanimation In A Recyclerview?

I'm trying to replace my GridView with the new RecyclerView (using GridLayoutManager) but it seems like it doesn't cope well with gridLayoutAnimation (ClassCastException: LayoutAni

Solution 1:

LayoutAnimationController is coupled into ViewGroup and both ListView and GridView extend the method below to provide the child's animationParams. The issue is that GridLayoutAnimationController requires its own AnimationParameters that cannot be class-casted.

/**
     * Subclasses should override this method to set layout animation
     * parameters on the supplied child.
     *
     * @param child the child to associate with animation parameters
     * @param params the child's layout parameters which hold the animation
     *        parameters
     * @param index the index of the child in the view group
     * @param count the number of children in the view group
     */protectedvoidattachLayoutAnimationParameters(View child,
            LayoutParams params, int index, int count) {
        LayoutAnimationController.AnimationParametersanimationParams=
                    params.layoutAnimationParameters;
        if (animationParams == null) {
            animationParams = newLayoutAnimationController.AnimationParameters();
            params.layoutAnimationParameters = animationParams;
        }

        animationParams.count = count;
        animationParams.index = index;
    }

Since this method by default adds a LayoutAnimationController.AnimationParameters instead of GridLayoutAnimationController.AnimationParameters, the fix should be to create and attach one beforehand. What we need to implement is what GridView already does:

@Override
protectedvoidattachLayoutAnimationParameters(View child,
        ViewGroup.LayoutParams params, int index, int count) {

    GridLayoutAnimationController.AnimationParameters animationParams =
            (GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;

    if (animationParams == null) {
        animationParams = new GridLayoutAnimationController.AnimationParameters();
        params.layoutAnimationParameters = animationParams;
    }

    animationParams.count = count;
    animationParams.index = index;
    animationParams.columnsCount = mNumColumns;
    animationParams.rowsCount = count / mNumColumns;

    if (!mStackFromBottom) {
        animationParams.column = index % mNumColumns;
        animationParams.row = index / mNumColumns;
    } else {
        final int invertedIndex = count - 1 - index;

        animationParams.column = mNumColumns - 1 - (invertedIndex % mNumColumns);
        animationParams.row = animationParams.rowsCount - 1 - invertedIndex / mNumColumns;
    }
}

To replicate GridView, the closest thing we can do is shoehorn the modifications into onBindViewHolder() which allows them to run before dispatchDraw, the call that triggers animations.

ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
        GridLayoutAnimationController.AnimationParameters animationParams = new GridLayoutAnimationController.AnimationParameters();
        params.layoutAnimationParameters = animationParams;

        animationParams.count = 9;
        animationParams.columnsCount = 3;
        animationParams.rowsCount = 3;
        animationParams.index = position;
        animationParams.column = position / animationParams.columnsCount;
        animationParams.row = position % animationParams.columnsCount;

If using RecyclerView's new GridLayoutManager, try getting parameters from that. The sample above is a proof of concept to show that it works. I've hardcoded values that don't exactly work for my application as well.

Since this is an API that's been around since API 1 with no real documentation or samples, I would highly suggest against using it, considering there are many ways to replicate its functionality.

Solution 2:

Simpler solution

TransitionManager.beginDelayedTransition(moviesGridRecycler);
gridLayoutManager.setSpanCount(gridColumns);
adapter.notifyDataSetChanged();

But don't forget to make your RecyclerAdapter setHasStableIds(true); and implement getItemID()

@OverridepubliclonggetItemId(int position) {
   return yourItemSpecificLongID;
}

Solution 3:

Quoting @Musenkishi at https://gist.github.com/Musenkishi/8df1ab549857756098ba

No clue. Are you calling recyclerView.scheduleLayoutAnimation(); after setting the adapter? And have you set android:layoutAnimation="@anim/your_layout_animation" to your <GridRecyclerView> in the layout?

This solved my issue.

Post a Comment for "How Do I Use A Gridlayoutanimation In A Recyclerview?"