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

时间:2016-06-17 20:08:51

标签: android android-layout animation android-recyclerview

根据Building a RecyclerView LayoutManager article我为RecyclerView创建了自己的自定义布局管理器,但是由于一些文档可用,我无法找到一种方法来强制从布局管理器内部重建视图重建动画(就像动画时一样)使用notifyItemInserted或notifyItemDeleted)。这些动画由recyclerView及其项目动画师控制,开发人员只能控制项目的位置。 所以我有一个方法fill,它根据当前滚动位置和布局管理器的状态执行子视图。从两个地方调用这种方法,

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

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
       detachAndScrapAttachedViews(recycler);
       fill(recycler);
    } 
    
  • 在scrollVerticallyBy中
  • /** 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(或布局管理器)来运行其动画?

2 个答案:

答案 0 :(得分:1)

当我们实现了自定义LayoutManager时,我们还为ExpandLayoutManager创建了自己的动画。特别是,我们使用ValueAnimator来设置LayoutManager外观的更改动画。如果您对我们的ExpandLayoutManager感到好奇,可以在GitHub上找到它。

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

答案 1 :(得分:0)

我调查了RecyclerView的来源,发现当onLayoutChildren执行自己的布局过程时会调用RecyclerView。因此,调用requestLayout应该是一个选项,而不是detachAndScrapAttachedViews。结合requestSimpleAnimationsInNextLayout它应该有所帮助。但不是。
只有在postOnAnimation runnable内执行时,这些操作才有效。所以,至少,我完成的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;
}