美文网首页
recyclerview分析

recyclerview分析

作者: popli | 来源:发表于2017-10-10 08:39 被阅读13次

    其实它的原理和listview差不多,但是架构更好,拓展性更强,它的滑动用的是view.offsetTopAndBottom,改变的是top和bottom的值

    它的复用依然是用detach和attach来完成的,复用还是有个复用容器,叫recycler和recyclerpool

    它将布局的责任交给了LayoutManager,而它自己负责大局的调度

    所以我们可以定义自己的LayoutManager,比如实现探探的卡片效果

    另外还有ItemTouchHelper,这个类很有用,可以用来自定义滑动效果,有drag和swipe两种操作

    还有Recycleview .ItemDecoration,用来画分割线

    还有Recycleview.ItemAnimator,定义view被添加,移动,删除时的动画

    Recycleview.OnItemTouchListener可以用来拦截触摸事件,定义自己的滑动行为,ItemTouchHelper内部就实现了这个接口

    还有OpRecorder,用来管理adapter的数据变化,比如添加,删除,移动,在RecyclerView的initAdapterManager()中初始化

    其实drag效果是监听触摸事件,然后进行item的滑动,这是第一步。第二步实现其他item的移动动画,是通过adapter的notifyItemMoved,而里面的动画实现是依靠改变每个item的位置参数,最后调用requestLayout来实现的

    支持drag和swipe两个事件,都支持四个方向。

    public void attachHelper(){
            ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ListCallback());
            itemTouchHelper.attachToRecyclerView(recycer);
    }
    
    public class ListCallback extends ItemTouchHelper.Callback{
    
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                int dragFlags = ItemTouchHelper.UP|ItemTouchHelper.DOWN;
                int swipeFlags  =ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
                int i = makeMovementFlags(dragFlags, swipeFlags);
                return i;
            }
    
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
    
                Log.i(TAG, "onMove: ");//位置不一样时才调用
                adapter.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
                return false;
            }
    
            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
                Log.i(TAG, "onSwiped: ");//默认为滑动距离超过一半,执行移出屏幕动画,动画结束后回调这个方法
            }
        }
    
     at android.view.ViewGroup.addViewInner(ViewGroup.java:4309)
                                                                           at android.view.ViewGroup.addView(ViewGroup.java:4145)
                                                                           at android.view.ViewGroup.addView(ViewGroup.java:4086)
                                                                           at android.support.v7.widget.RecyclerView$4.addView(RecyclerView.java:544)
                                                                           at android.support.v7.widget.ChildHelper.addView(ChildHelper.java:107)
                                                                           at android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:6314)
                                                                           at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:6272)
                                                                           at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:6260)
                                                                           at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1385)
                                                                           at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1334)
                                                                           at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:563)
                                                                           at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2847)
                                                                           at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3145)
                                                                           at android.view.View.layout(View.java:16630)
                                                                           at android.view.ViewGroup.layout(ViewGroup.java:5437)
                                                                           at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
    

    可以重写ItemTouchHelper.Callback中的onChildDraw来实现侧滑删除,这个方法默认实现是将item进行translationX操作,在老版本中是canvas的平移,我们根据dx,dy的条件判断进行滑动限制即可
    还需要重写手指抬起事件,因为默认实现是到一定速度或者滑动距离大于一个值,就进行ondismiss操作
    当然你还要自己加上 上下滑动时自动关闭“delete”

    当然drag操作也很好实现,你可以用GridLayoutManager,然后只允许drag操作即可

    还有一种实现是当年很火的“瀑布流”,这个用StaggeredLayoutManager就能实现

    相关文章

      网友评论

          本文标题:recyclerview分析

          本文链接:https://www.haomeiwen.com/subject/fgxmyxtx.html