RecyclerView是官方推荐取代ListView的空间,如何实现RecyclerView列表元素的拖动呢?
官方提供了ItemTouchHelper类使用步骤如下:
- 定义ItemTouchHelper.Callback实现类,以下是几个重要的方法
package com.zms.copyapp.helper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
/**
* Created by Msn on 2015/7/28.
*/
public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback{
private ItemTouchListener mItemTouchListener;
public MyItemTouchHelperCallback(ItemTouchListener itemTouchListener){
mItemTouchListener = itemTouchListener;
}
/**
* 支持长按进入拖动
* @return
*/
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
/**
* 指定拖动和滑动支持的方向
* @param recyclerView
* @param viewHolder
* @return
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//List部分功能
// int dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;//拖动支持向下和向上
// int swipeFlag = ItemTouchHelper.START | ItemTouchHelper.END;//滑动支持向左和向右
//Grid部分功能
int dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN |ItemTouchHelper.START | ItemTouchHelper.END;
int swipeFlag = 0;
return makeMovementFlags(dragFlag,swipeFlag);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
Log.e("Test","onMove--------------------------------");
mItemTouchListener.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
Log.e("Test", "onSwiped--------------------------------");
mItemTouchListener.onItemDismiss(viewHolder.getAdapterPosition());
}
/**
* 在每次View Holder的状态变成拖拽 (ACTION_STATE_DRAG) 或者 滑动 (ACTION_STATE_SWIPE)的时候被调用。
* @param viewHolder
* @param actionState
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if(actionState != ItemTouchHelper.ACTION_STATE_IDLE){
ItemStatusListener listener = (ItemStatusListener)viewHolder;
listener.onItemSelected();
}
super.onSelectedChanged(viewHolder, actionState);
}
/**
* 在一个view被拖拽然后被放开的时候被调用,
* @param recyclerView
* @param viewHolder
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
ItemStatusListener listener = (ItemStatusListener)viewHolder;
listener.onItemClear();
}
}
- 声明ItemTouchHelper,并绑定到待管理的RecyclerView上
ItemTouchHelper.Callback helperCallback = new MyItemTouchHelperCallback(adapter);
helper = new ItemTouchHelper(helperCallback);
helper.attachToRecyclerView(recyclerView);
- 在Adapter中定义滑动删除和拖动排序的数据逻辑
package com.zms.copyapp;
import android.graphics.Color;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.zms.copyapp.helper.ItemStatusListener;
import com.zms.copyapp.helper.ItemTouchListener;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by Msn on 2015/7/28.
*/
public class MyRecyclerListAdapter extends RecyclerView.Adapter<MyRecyclerListAdapter.MyViewHolder>
implements ItemTouchListener{
public final static String[] STR_ARRAY = {"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGTH","NINE","TEN"};
private final List<String> mItems = new ArrayList<>();
private OnDragListener dragListener;
public MyRecyclerListAdapter(OnDragListener listener) {
mItems.addAll((Arrays.asList(STR_ARRAY)));
dragListener = listener;
}
@Override
public void onItemMove(int fromPosition, int toPosition) {
String prev = mItems.remove(fromPosition);
mItems.add(toPosition > fromPosition ? toPosition - 1 : toPosition, prev);
notifyItemMoved(fromPosition,toPosition);
}
@Override
public void onItemDismiss(int position) {
mItems.remove(position);
notifyItemRemoved(position);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main,parent,false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.textView.setText(mItems.get(position));
holder.handleImgv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(MotionEventCompat.getActionMasked(motionEvent)
== MotionEvent.ACTION_DOWN){
dragListener.onStartDrag(holder);
Log.e("Test","onTouch.ACTION_DOWN");
}
return false;
}
});
}
@Override
public int getItemCount() {
return mItems.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements ItemStatusListener{
public ImageView handleImgv;
public TextView textView;
public MyViewHolder(View view){
super(view);
textView = (TextView)view.findViewById(R.id.text);
handleImgv = (ImageView)view.findViewById(R.id.handle);
}
@Override
public void onItemSelected() {
itemView.setBackgroundColor(Color.LTGRAY);
}
@Override
public void onItemClear() {
itemView.setBackgroundColor(Color.TRANSPARENT);
}
}
public interface OnDragListener{
public void onStartDrag(MyViewHolder holder);
public void onStartSwipe(MyViewHolder holder);
}
}
这样一个拖动重排的功能就实现了: