androidandroid-layoutanimationandroid-recyclerview

Recycler's view custom layout manager animation


According to the Building a RecyclerView LayoutManager article I have created own custom layout manager for RecyclerView, but due to a few documentation available i can't find a way to force recycle view rebuild animation inside from layout manager ( just like animations when notifyItemInserted or notifyItemDeleted is used). Such animations are controlled by recyclerView and its item animators, developer only can control position of items. So i have a method fill, which performs placing child views according to current scroll position and state of layout manager. Such method is called from two places,

And i want in case of some condition perform a bit more complex transition for some views and with animation.
It may be reached if somehow initiate layouting childrens flow, when onLayoutChildren method will be invoked by RecyclerView.
I'm able to do this with detachAndScrapAttachedViews(recycler) and that initiates onLayoutChildren and running default fill process, but such transition will be performed instantly without any animation.

Is it possible to force recyclerView (or layout manager) inside from layout manager to run its animations?


Solution

  • I've investigated the source of RecyclerView and found that onLayoutChildren is called when RecyclerView performs own layouting process. So calling requestLayout should be an option, instead of detachAndScrapAttachedViews. And with combination of requestSimpleAnimationsInNextLayout it should help. But NOT.
    Those operations would work only if been performed inside postOnAnimation runnable. So, at least, with my completed scrollVerticalBy my layout manager've been running animations successfully:

    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        dy = scrollVerticallyInternal(dy);
        offsetChildrenVertical(-dy);
        postOnAnimation(new Runnable() {
            @Override
            public void run() {
                requestLayout();
                requestSimpleAnimationsInNextLayout();
            }
        });
    
        fill(recycler);
        return dy;
    }