RecyclerView实现拖动排序和滑动删除功能

移动开发 作者: 2024-08-22 00:10:01
RecyclerView 的拖动排序需要借助一下 ItemTouchHelper 这个类,ItemTouchHelper 类是 Google 提供的一个支持 RecyclerView 滑动和拖动的一个

ItemTouchHelper.Callback

getMovementFlags

public abstract int getMovementFlags(RecyclerView recyclerView,ViewHolder viewHolder);

onMove

public abstract boolean onMove(RecyclerView recyclerView,ViewHolder viewHolder,ViewHolder target);

onSwiped

public abstract void onSwiped(ViewHolder viewHolder,int direction);

onSelectedChanged

public void onSelectedChanged(ViewHolder viewHolder,int actionState) {
        if (viewHolder != null) {
            sUICallback.onSelected(viewHolder.itemView);
        }
}

clearView

public void clearView(RecyclerView recyclerView,ViewHolder viewHolder) {
        sUICallback.clearView(viewHolder.itemView);
}

RecyclerView实现拖动排序

@Override
public void onMove(int fromPosition,int toPosition) {
    if (fromPosition < toPosition) {
        for (int i = fromPosition; i < toPosition; i++) {
            Collections.swap(list,i,i + 1);
        }
    } else {
        for (int i = fromPosition; i > toPosition; i--) {
            Collections.swap(list,i - 1);
        }
    }
    notifyItemMoved(fromPosition,toPosition);
}

RecyclerView实现侧滑删除


    @Override
    public void onSwiped(int position) {
        Log.i("drag","onSwiped");
        list.remove(position);
        notifyItemRemoved(position);
    }

参考代码

ItemTouchHelper.Callback 的实现类

/**
 * Created by jzman on 2017/5/17 0015.
 */
public class ItemTouchCallBack extends ItemTouchHelper.Callback {
    private static final String TAG = "drag";
    private OnItemTouchListener onItemTouchListener;

    public void setOnItemTouchListener(OnItemTouchListener onItemTouchListener) {
        this.onItemTouchListener = onItemTouchListener;
    }

    /**
     * 根据 RecyclerView 不同的布局管理器,设置不同的滑动、拖动方向
     * 该方法使用 makeMovementFlags(int dragFlags,int swipeFlags) 方法返回
     * 参数: dragFlags:拖动的方向
     *      swipeFlags:滑动的方向
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder) {
        Log.i(TAG,"getMovementFlags");
        if (recyclerView.getLayoutManager() instanceof GridLayoutManager ||
                recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager){
            //此处不需要进行滑动操作,可设置为除4和8之外的整数,这里设为0
            //不支持滑动
            return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN |
                                   ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT,0 );
        }else {
            //如果是LinearLayoutManager则只能向上向下滑动,
            //此处第二个参数设置支持向右滑动
            return makeMovementFlags(ItemTouchHelper.UP   | ItemTouchHelper.DOWN,ItemTouchHelper.RIGHT );
        }
    }

    /**
     * 当 ItemTouchHelper 拖动一个Item时该方法将会被回调,Item将从旧的位置移动到新的位置
     * 如果不拖动这个方法将从来不会调用,返回true表示已经被移动到新的位置
     * @param recyclerView
     * @param viewHolder
     * @param target
     * @return
     */
    @Override
    public boolean onMove(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder,RecyclerView.ViewHolder target) {
        Log.i(TAG,"onMove");
        int fromPosition = viewHolder.getAdapterPosition();
        int toPosition   = target.getAdapterPosition();
        onItemTouchListener.onMove(fromPosition,toPosition);
        return true;
    }

    /**
     * 当Item被滑动的时候被调用
     * 如果你不滑动这个方法将不会被调用
     * @param viewHolder
     * @param direction
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder,int direction) {
        Log.i(TAG,"onSwiped");
        //此处是侧滑删除的主要代码
        int position = viewHolder.getAdapterPosition();
        onItemTouchListener.onSwiped(position);
    }

    /**
     * 当Item被滑动、拖动的时候被调用
     * @param viewHolder
     * @param actionState
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder,int actionState) {
        Log.i(TAG,"onSelectedChanged");
        //...
        super.onSelectedChanged(viewHolder,actionState);
    }

    /**
     * 当与用户交互结束或相关动画完成之后被调用
     * @param recyclerView
     * @param viewHolder
     */
    @Override
    public void clearView(RecyclerView recyclerView,"clearView");
        //...
        super.clearView(recyclerView,viewHolder);
    }

    /**
     * 移动交换数据的更新监听
     */
    public interface OnItemTouchListener {
        //拖动Item时调用
        void onMove(int fromPosition,int toPosition);
        //滑动Item时调用
        void onSwiped(int position);
    }
}

Adapter的实现

/**
 * Created by jzman on 2017/05/17 0009.
 * RecycleView的Adapter
 */
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.DataViewHolder> implements View.OnClickListener,ItemTouchCallBack.OnItemTouchListener {
    private Context context;
    private List<SimpleTitleGrid> list;

    public GridAdapter(Context context,List<SimpleTitleGrid> list) {
        this.context = context;
        this.list = list;
    }

    /**
     * 创建ViewHolder
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public DataViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
        //加载item布局文件(每一个)
        View view = LayoutInflater.from(context).inflate(R.layout.item,null);

        //为View设置单击事件
        view.setOnClickListener(this);
        DataViewHolder viewHolder = new DataViewHolder(view);

        //使用代码设置宽高(xml布局设置无效时)
        view.setLayoutParams(new RecyclerView.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
        return viewHolder;
    }

    /**
     * 绑定数据
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(DataViewHolder holder,int position) {
        //设置每一个Item的高度
        holder.textView.setText(list.get(position).getTitle());
    }

    /**
     * 选项总数
     * @return
     */
    @Override
    public int getItemCount() {
        return list.size();
    }

    /**
     * 单击事件
     * @param v
     */
    @Override
    public void onClick(View v) {
        if(onItemClickListener!=null){
            int position = recyclerView.getChildAdapterPosition(v);
            //程序执行到此,会执行该方法的具体实现
            onItemClickListener.onItemClick(recyclerView,v,position,list.get(position));
        }
    }

    @Override
    public void onMove(int fromPosition,int toPosition) {
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(list,i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(list,i - 1);
            }
        }
        notifyItemMoved(fromPosition,toPosition);
    }

    @Override
    public void onSwiped(int position) {
        Log.i("drag","onSwiped");
        list.remove(position);
        notifyItemRemoved(position);
    }

    /**
     *  RecycleView中针对ViewHolder来实现
     */
    public static class DataViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        public DataViewHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.tv_grid);
        }
    }
    private RecyclerView recyclerView;
    private  OnItemClickListener onItemClickListener;
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
    /**
     * 设计recycleView选项单击事件的回调接口(给外面使用)
     * 参考ListView选项单击事件方法
     */
    public interface OnItemClickListener{
        //参数(父组件,点击的View,位置,这里可能是某个对象的id或对象/这里不需要)
        void onItemClick(RecyclerView recyclerView,View view,int position,SimpleTitleGrid obj);
    }
    /**
     *   将RecycleView附加到Adapter上
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        this.recyclerView= recyclerView;
    }
    /**
     *   将RecycleView从Adapter解除
     */
    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        this.recyclerView = null;
    }
}

MainActivity

/**
 * Created by jzman on 2017/05/17 0029.
 * RecycleView的Adapter
 */
public class MainActivity extends AppCompatActivity implements GridAdapter.OnItemClickListener{
    private RecyclerView rv_user;
    private GridAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        rv_user = (RecyclerView) findViewById(R.id.rv_user);
        adapter = new GridAdapter(this,DataUtils.getUserGrids());

        ItemTouchCallBack touchCallBack = new ItemTouchCallBack();
        touchCallBack.setOnItemTouchListener(adapter);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(touchCallBack);

        rv_user.setLayoutManager(new GridLayoutManager(this,3));
//        rv_user.setLayoutManager(new LinearLayoutManager(this));
        rv_user.setAdapter(adapter);
        itemTouchHelper.attachToRecyclerView(rv_user);

        adapter.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(RecyclerView recyclerView,int position,SimpleTitleGrid obj) {
        Toast.makeText(MainActivity.this,obj.getTitle(),Toast.LENGTH_SHORT).show();
    }
}

显示效果

GridLayoutManager LinearLayoutManager
原创声明
本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
本文链接:http://www.jiecseo.com/news/show_66370.html