Recycler 的视图自定义布局管理器动画

问题描述 投票:0回答:2

根据构建RecyclerView LayoutManager文章我已经为RecyclerView创建了自己的自定义布局管理器,但是由于一些可用的文档,我找不到一种方法来强制从布局管理器内部回收视图重建动画(就像动画时一样)使用notifyItemInserted 或notifyItemDeleted)。此类动画由 recyclerView 及其项目动画师控制,开发人员只能控制项目的位置。 所以我有一个方法

fill
,它根据当前滚动位置和布局管理器的状态来放置子视图。这样的方法是从两个地方调用的,

  • 在onLayoutChildren中(当布局管理器执行项目的初始化放置或数据集更改时调用此方法)

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
       detachAndScrapAttachedViews(recycler);
       fill(recycler);
    } 
    
  • 在垂直滚动中

    /** calculate offset of views while scrolling, layout items on new places*/
    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        dy = scrollVerticallyInternal(dy);
        offsetChildrenVertical(-dy);
        if (condition) {
            //todo refactor it, blinking now without animation. 
            detachAndScrapAttachedViews(recycler);
        }
    
        fill(recycler);
        return dy;
    }
    

我希望在某些情况下

condition
对某些视图和动画执行更复杂的转换。
如果以某种方式启动布局子流程,当 RecyclerView 调用
onLayoutChildren
方法时,可能会达到此目的。
我可以使用
detachAndScrapAttachedViews(recycler)
来执行此操作,并启动
onLayoutChildren
并运行默认的
fill
进程,但这种转换将立即执行,没有任何动画。

是否可以从布局管理器中强制recyclerView(或布局管理器)运行其动画?

android android-layout animation android-recyclerview
2个回答
2
投票

当我们实现了自定义的LayoutManager之后,我们也为ExpandLayoutManager制作了自己的动画。特别是,我们使用 ValueAnimator 来动画化 LayoutManager 外观的变化。如果您对我们的 ExpandLayoutManager 感到好奇,可以在 GitHub 上找到它。

在这里您还可以找到一些创建自定义 LayoutManager 的有价值的详细信息:http://cases.azoft.com/create-custom-layoutmanager-android/


1
投票

我调查了

RecyclerView
的来源,发现当
onLayoutChildren
执行自己的布局过程时,会调用
RecyclerView
。因此,调用
requestLayout
应该是一种选择,而不是
detachAndScrapAttachedViews
。结合
requestSimpleAnimationsInNextLayout
应该会有所帮助。但不是。
这些操作只有在
postOnAnimation
可运行内部执行时才有效。所以,至少,随着我完成的
scrollVerticalBy
,我的布局管理器已经成功运行动画了:

@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;
}
© www.soinside.com 2019 - 2024. All rights reserved.