美文网首页
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