列表拖動排序功能也算是比較常見的了。在RecycleView還沒有出現(xiàn)的那個年代苹威,依稀記得是重寫GridView
實(shí)現(xiàn)拖拽昆咽,WindowManager
實(shí)現(xiàn)拖拽的鏡像。
不過牙甫,現(xiàn)在好了掷酗,有了RecycleView
之后,一切都變得簡單了窟哺。因?yàn)?code>RecycleView提供了拖動的回調(diào)ItemTouchHelper.Callback
泻轰,通過實(shí)現(xiàn)該類,會讓我們少寫很多代碼且轨。
先看一下浮声,簡化后的Demo效果圖。
這里的實(shí)現(xiàn)的效果是:
① 第一個標(biāo)簽不可編輯
② 除了第一個標(biāo)簽外旋奢,其它標(biāo)簽可拖拽排序和刪除
ItemTouchHelper.Callback的實(shí)現(xiàn)類
public class ItemDragCallback extends ItemTouchHelper.Callback {
private ChannelAdapter mAdapter;
private boolean mEdit;
public ItemDragCallback(ChannelAdapter mAdapter) {
this.mAdapter = mAdapter;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
ChannelAdapter adapter = (ChannelAdapter) recyclerView.getAdapter();
mEdit = adapter.isEdit;
//是否是編輯狀態(tài)
if (!mEdit) {
return 0;
}
int position = viewHolder.getLayoutPosition();
//第一個item不用交換
if (position == 0) {
return 0;
}
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition(); //拖動的position
int toPosition = target.getAdapterPosition(); //釋放的position
int position = viewHolder.getLayoutPosition();
//第一個item不用交換
if (position == 0) {
return false;
}
mAdapter.itemMove(fromPosition, toPosition);
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
if (dX != 0 && dY != 0 || isCurrentlyActive) {
ChannelAdapter adapter = (ChannelAdapter) recyclerView.getAdapter();
mEdit = adapter.isEdit;
}
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
if (actionState == ACTION_STATE_DRAG) {
//長按時調(diào)用
ChannelAdapter.ChannelHolder holder = (ChannelAdapter.ChannelHolder) viewHolder;
holder.name.setBackgroundColor(Color.parseColor("#FDFDFE"));
holder.name.setBackground(ContextCompat.getDrawable(ProjectApp.getApp(), R.drawable.shape_channel_bg));
holder.delete.setVisibility(View.GONE);
}
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
//松手時調(diào)用
ChannelAdapter.ChannelHolder holder = (ChannelAdapter.ChannelHolder) viewHolder;
holder.name.setBackground(ContextCompat.getDrawable(ProjectApp.getApp(), R.drawable.shape_channel_bg));
holder.delete.setVisibility(View.VISIBLE);
}
}
public class ChannelAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<ChannelBean> mSortedList;
public boolean isEdit;//是否是編輯狀態(tài)
public ChannelAdapter(Context mContext, List<ChannelBean> list) {
this.mContext = mContext;
mSortedList = list;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_channel, parent, false);
return new ChannelHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
setChannel((ChannelHolder) holder, mSortedList.get(position));
}
private void setChannel(final ChannelHolder holder, final ChannelBean bean) {
holder.name.setText(bean.getName());
int position = holder.getLayoutPosition();
//點(diǎn)擊標(biāo)簽刪除已選標(biāo)簽
holder.name.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!bean.isLock()) {
if (isEdit) {
removeFromSelected(holder);
}
} else {
}
}
});
//長按進(jìn)入編輯狀態(tài)
holder.name.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
isEdit = true;
notifyDataSetChanged();
//返回true 防止長按拖拽事件跟點(diǎn)擊事件沖突
return true;
}
});
//點(diǎn)擊X刪除已選標(biāo)簽
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
removeFromSelected(holder);
}
});
//是否是編輯狀態(tài)且第一個不可編輯
if (isEdit&&position!=0) {
holder.delete.setVisibility(View.VISIBLE);
} else {
holder.delete.setVisibility(View.GONE);
}
}
/**
* 刪除已選標(biāo)簽
* @param holder
*/
private void removeFromSelected(ChannelHolder holder) {
int position = holder.getLayoutPosition();
holder.delete.setVisibility(View.GONE);
notifyItemRemoved(position);
mSortedList.remove(position);
notifyDataSetChanged();
}
/**
* 對拖拽的元素進(jìn)行排序
* @param fromPosition
* @param toPosition
*/
void itemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(mSortedList, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(mSortedList, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
}
@Override
public int getItemCount() {
return mSortedList == null ? 0 : mSortedList.size();
}
class ChannelHolder extends RecyclerView.ViewHolder {
TextView name;
ImageView delete;
public ChannelHolder(View itemView) {
super(itemView);
int validWidth = ScreenUtil.getScreenWidth() - Px2DpUtil.dp2px(mContext, 45);
int childWidth = validWidth / 4;
name = (TextView) itemView.findViewById(R.id.channel_name);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(childWidth, Px2DpUtil.dp2px(mContext, 35));
params.setMargins(0, Px2DpUtil.dp2px(mContext, 5), 0, 0);
name.setLayoutParams(params);
name.setGravity(Gravity.CENTER);
delete = (ImageView) itemView.findViewById(R.id.channel_delete);
}
}
}
調(diào)用就比較簡單了
ItemDragCallback callback = new ItemDragCallback(mAdapter);
ItemTouchHelper helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(mRecyclerView);
到這里就結(jié)束了泳挥。