Recyclerview 实现拖拽

       private List datas = new ArrayList<>();
        // 编辑完成之后的tab 集合
       private List 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 categorys;

public List getCategorys() {
    return categorys;
}

public void setCategorys(List 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 {

private final Context mContext;
private List mTopBeanList = new ArrayList<>();
private OnDetailClickLister onDetailClickListener;
private OnDragLister onDragLister;

public TabAdapter(Context context) {
    mContext = context;
}

public void setData(List list) {
    this.mTopBeanList.clear();
    this.mTopBeanList.addAll(list);
    notifyDataSetChanged();
}

public void addData(List 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 布局】

 



 

【drawable】








【注意】点击某一个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 实现拖拽)