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;
}
}
}