美文网首页
Recyclerview 实现拖拽

Recyclerview 实现拖拽

作者: zhengLH | 来源:发表于2019-01-04 16:38 被阅读3次
           private List<TopTabBean.CategorysBean> datas = new ArrayList<>();
            // 编辑完成之后的tab 集合
           private List<TopTabBean.CategorysBean> mEditFinishTabList = new ArrayList<>(); 
            mRvTab.setVerticalScrollBarEnabled(false);
            mRvTab.setHorizontalFadingEdgeEnabled(false);
    
            // 设置RecyclerView 不可滚动
            mRvTab.setNestedScrollingEnabled(false);
            mRvTab.setOverScrollMode(View.OVER_SCROLL_NEVER);
            mRvTab.setHasFixedSize(true);
    
            mAdapter = new TabAdapter(ShellMoreTabActivity.this);
            NoScrollGridLayoutManager manager = new NoScrollGridLayoutManager(ShellMoreTabActivity.this, 4);   //  设置4列
            manager.setScrollEnabled(false);  //  设置网格布局不可滚动
            mRvTab.setLayoutManager(manager);
    
            mItemTouchHelper = new ItemTouchHelper(new TabCallback());
            mItemTouchHelper.attachToRecyclerView(mRvTab);
            mAdapter.setData(datas);
            mRvTab.setAdapter(mAdapter);
    
             // 进入 某一个 频道
            mAdapter.setOnDetailClickListener(new TabAdapter.OnDetailClickLister() {
                @Override
                public void onItemClick(int position, int id) {
                        // todo
                }
            });
            mAdapter.setOnItemDragListener(new TabAdapter.OnDragLister() {
                @Override
                public void onItemDrag(int position, TabAdapter.TabNewsHolder holder) {
    
                     // 只有 不被锁住的元素才可以拖动
                    if (!datas.get(position).getLocked()) {
                        mItemTouchHelper.startDrag(holder);
                    }
                }
            });
    

    【不滚动网格布局】

    /**
     * @Author Lee
     * @Time 2018/9/17
     * @Theme  自定义 不滚动网格布局
    */
    
    public class NoScrollGridLayoutManager extends GridLayoutManager {
    
    private boolean isScrollEnabled = true;
    public NoScrollGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    
    public NoScrollGridLayoutManager(Context context, int spanCount) {
        super(context, spanCount);
    }
    
    public NoScrollGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
        super(context, spanCount, orientation, reverseLayout);
    }
    
    public void setScrollEnabled(boolean flag) {
        this.isScrollEnabled = flag;
    }
    
    @Override
    public boolean canScrollVertically() {
        return isScrollEnabled && super.canScrollVertically() ;
    }
    
    @Override
    public boolean canScrollHorizontally() {
        return isScrollEnabled && super.canScrollHorizontally();
       }
    }
    

    【TabCallback 】 实现拖动的接口类,需要重写很多方法:

      class TabCallback extends ItemTouchHelper.Callback {
    
        private boolean isFirstDragUnable = false;
        private boolean isSwipeEnable = true;
    
        /**
         * 这个方法是设置是否滑动时间,以及拖拽的方向,所以在这里需要判断一下是列表布局还是网格布局,
         * 如果是列表布局的话则拖拽方向为DOWN和UP,如果是网格布局的话则是DOWN和UP和LEFT和RIGHT
         *
         * @param recyclerView
         * @param viewHolder
         * @return
         */
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    
            if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
                        ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
                final int swipeFlags = 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            } else {
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                final int swipeFlags = 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            }
        }
    
    
        /**
         * onMove()方法则是我们在拖动的时候不断回调的方法,在这里我们需要将正在拖拽的item和集合的item进行交换元素,然后在通知适配器更新数据
         *
         * @param recyclerView
         * @param viewHolder
         * @param target
         * @return
         */
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
    
            //得到当拖拽的viewHolder的Position
            int fromPosition = viewHolder.getAdapterPosition();
            //拿到当前拖拽到的item的viewHolder
            int toPosition = target.getAdapterPosition();
    
            if(datas.get(fromPosition).getLocked() || datas.get(toPosition).getLocked()){
                // 不可拖拽(包括 不可拖拽到其他地方 或者 其他地方拖拽到 这里 )
                return false;
            }else{
    
                if (fromPosition < toPosition) {
                    for (int i = fromPosition; i < toPosition; i++) {
                        Collections.swap(datas, i, i + 1);
                    }
                } else {
                    for (int i = fromPosition; i > toPosition; i--) {
                        Collections.swap(datas, i, i - 1);
                    }
                }
                mAdapter.notifyItemMoved(fromPosition, toPosition);
                return true;
    
            }
    
        }
    
        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int actionState) {
            /*
            ACTION_STATE_IDLE:闲置状态
            ACTION_STATE_SWIPE:滑动状态
            ACTION_STATE_DRAG:拖拽状态*/
    
            if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
                viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
            }
            super.onSelectedChanged(viewHolder, actionState);
        }
    
    
        /**
         * 手指松开的时候还原
         *
         * @param recyclerView
         * @param viewHolder
         */
        @Override
        public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            super.clearView(recyclerView, viewHolder);
            viewHolder.itemView.setBackgroundColor(Color.WHITE);
            mEditFinishTabList = datas;  // 得到重新排序后最终的元素集合
            mAdapter.setData(mEditFinishTabList);
    
            // 监听 结束拖拽:
         /*    mTvTabEdit.setTextColor(getResources().getColor(R.color.colorAccent));
            mTabHint.setText(mChannelHint);
            mTvTabEdit.setText(mEdit);*/
    
        }
    
        /**
         * 重写拖拽不可用
         *
         * @return
         */
        @Override
        public boolean isLongPressDragEnabled() {
            return isFirstDragUnable;
        }
    
         /**
         * 滑动
         * @return
         */
        @Override
        public boolean isItemViewSwipeEnabled() {
            return isSwipeEnable;
        }
    }
    

    【元素】TopTabBean

    public class TopTabBean{
    
    private ResultBean result;
    private List<CategorysBean> categorys;
    
    public List<CategorysBean> getCategorys() {
        return categorys;
    }
    
    public void setCategorys(List<CategorysBean> categorys) {
        this.categorys = categorys;
    }
    
    public static class CategorysBean{
    
        private int id;
        private String  categoryCode;
        private String  categoryName;
        private Boolean   locked;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getCategoryCode() {
            return categoryCode;
        }
    
        public void setCategoryCode(String categoryCode) {
            this.categoryCode = categoryCode;
        }
    
        public String getCategoryName() {
            return categoryName;
        }
    
        public void setCategoryName(String categoryName) {
            this.categoryName = categoryName;
        }
    
        public Boolean getLocked() {
            return locked;
        }
    
        public void setLocked(Boolean locked) {
            this.locked = locked;
        }
    
        }
    }
    

    【设配器】TabAdapter

      /**
     * @Author Lee
     * @Time 2018/8/10
     * @Theme
    */
    public class TabAdapter extends XRecyclerView.Adapter<TabAdapter.TabNewsHolder> {
    
    private final Context mContext;
    private List<TopTabBean.CategorysBean> mTopBeanList = new ArrayList<>();
    private OnDetailClickLister onDetailClickListener;
    private OnDragLister onDragLister;
    
    public TabAdapter(Context context) {
        mContext = context;
    }
    
    public void setData(List<TopTabBean.CategorysBean> list) {
        this.mTopBeanList.clear();
        this.mTopBeanList.addAll(list);
        notifyDataSetChanged();
    }
    
    public void addData(List<TopTabBean.CategorysBean> list) {
        this.mTopBeanList.addAll(list);
        notifyDataSetChanged();
    }
    
    
    @Override
    public TabAdapter.TabNewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View mView = LayoutInflater.from(mContext).inflate(R.layout.item_shell_tab, parent, false);
        return new TabNewsHolder(mView);
    }
    
    @Override
    public void onBindViewHolder(final TabAdapter.TabNewsHolder holder, final int position) {
    
        if(mTopBeanList.get(position).getLocked()){
    
            holder.mTvTabCategory.setTextColor(mContext.getResources().getColor(R.color.colorAccent));
            holder.mTvTabCategory.setBackgroundResource(R.drawable.shape_rect_gray_solid_blue_stroke);
        }
    
        holder.mTvTabCategory.setText(mTopBeanList.get(position).getCategoryName());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onDetailClickListener.onItemClick(position, mTopBeanList.get(position).getId() );
            }
        });
    
        // 拖拽
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                onDragLister.onItemDrag(position, holder);
                return true;
            }
        });
    
    }
    
    
    @Override
    public int getItemCount() {
    
        return mTopBeanList != null ? mTopBeanList.size() : 0;
    }
    
    
    public class TabNewsHolder extends XRecyclerView.ViewHolder {
    
        private TextView mTvTabCategory;
    
        public TabNewsHolder(View itemView) {
            super(itemView);
    
            mTvTabCategory = itemView.findViewById(R.id.tv_tab_category);
        }
    }
    
    
    public void setOnDetailClickListener(OnDetailClickLister onDetailClickListener) {
        this.onDetailClickListener = onDetailClickListener;
    }
    
    public void setOnItemDragListener(OnDragLister onDragLister) {
        this.onDragLister = onDragLister;
    }
    
    public interface OnDetailClickLister {
        void onItemClick(int position, int id);
    }
    
    public interface OnDragLister {
    
        void onItemDrag(int position, TabAdapter.TabNewsHolder holder);
           }
       }
    

    【xml 布局】

     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
    
    <TextView
        android:id="@+id/tv_tab_category"
        android:text="体育"
        android:layout_margin="7dp"
        android:gravity="center"
        android:textColor="@color/shell_font_black"
        android:background="@drawable/shape_rect_light_gray_solid"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:textSize="15sp"
        android:layout_width="75dp"
        android:layout_height="wrap_content"/>
    
     </LinearLayout>
    

    【drawable】

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    
    <stroke android:width="1dp"
        android:color="@color/colorAccent" />
    <solid android:color="@color/background"/>
    <corners android:radius="3dp" />
    </shape>
    

    【注意】点击某一个tab,跳转到相对应的Fragment.

      /**
     *  切换到某一个目录分类
     *
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void switchEvent(JumpToCategoryEvent event) {
        String categoryName = event.getCategoryName();
        for(int i =0; i< mTabList.size(); i++){
            if(categoryName.equals(mTabList.get(i).getCategoryName())){
                mVp.setCurrentItem(i);
                break;
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Recyclerview 实现拖拽

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