使用RecyclerView实现item拖拽变换位置重新排序

小知识解决大问题,问题处理+经验分享,大家好,我是时代新人!今天给大家分享一个小例子,请往下看:

今天用RecyclerView实现一个拖拽交换位置,和编辑删除的功能。先来个效果图看一下

1、定义一个ItemTouchHelperAdapter接口

import androidx.recyclerview.widget.RecyclerView;

/**
 * Created by WJY.
 * Date: 2021-03-16
 * Time: 10:45
 * Description: 定义RecycleView的Adapter和SimpleItemTouchHelperCallback直接交互的接口方法
 */
public interface ItemTouchHelperAdapter {

    //数据交换
    void onItemMove(RecyclerView.ViewHolder source, RecyclerView.ViewHolder target);

    //数据删除
    void onItemDissmiss(RecyclerView.ViewHolder source);

    //drag或者swipe选中
    void onItemSelect(RecyclerView.ViewHolder source);

    //状态清除
    void onItemClear(RecyclerView.ViewHolder source);
}

2、定义SimpleItemTouchHelperCallback类来处理RecycleView的选中、拖拽移动、拖拽删除等的实现

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

/**
 * Created by WJY.
 * Date: 2021-03-16
 * Time: 10:50
 * Description: 处理RecycleView的选中,拖拽移动,拖拽删除的实现类
 */
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {

    private ItemTouchHelperAdapter mAdapter;

    public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
        mAdapter = adapter;
    }

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        //int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; //允许上下的拖动
        //int dragFlags =ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; //允许左右的拖动
        //int swipeFlags = ItemTouchHelper.LEFT; //只允许从右向左侧滑
        //int swipeFlags = ItemTouchHelper.DOWN; //只允许从上向下侧滑
        //一般使用makeMovementFlags(int,int)或makeFlag(int, int)来构造我们的返回值
        //makeMovementFlags(dragFlags, swipeFlags)

        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; //允许上下左右的拖动
        return makeMovementFlags(dragFlags, 0);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        //通过接口传递拖拽交换数据的起始位置和目标位置的ViewHolder
        mAdapter.onItemMove(viewHolder, target);
        return true;
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;//长按启用拖拽
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
        return false; //不启用拖拽删除
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        //移动删除回调,如果不用可以不用理
        // mAdapter.onItemDissmiss(viewHolder);
    }

    @Override
    public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            //当滑动或者拖拽view的时候通过接口返回该ViewHolder
            mAdapter.onItemSelect(viewHolder);
        }
    }

    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        if (!recyclerView.isComputingLayout()) {
            //当需要清除之前在onSelectedChanged或者onChildDraw,onChildDrawOver设置的状态或者动画时通过接口返回该ViewHolder
            mAdapter.onItemClear(viewHolder);
        }
    }
}

3、写我们的拖拽adapter类DragRecyclerViewAdapter

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.test1.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by WJY.
 * Date: 2021-03-16
 * Time: 10:24
 * Description: 拖拽的recyclerView 的  adapter
 */
public class DragRecyclerViewAdapter extends RecyclerView.Adapter<DragRecyclerViewAdapter.DragHolder> implements ItemTouchHelperAdapter {

    private Context context;
    private List<String> contentList = new ArrayList<>();
    private boolean isShowDelete = false;//是否显示删除图标

    public DragRecyclerViewAdapter(Context context, List<String> contentList) {
        this.context = context;
        this.contentList = contentList;
    }

    @NonNull
    @Override
    public DragHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_drag_recyclerview, parent, false);
        return new DragHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final DragHolder holder, int position) {
        if (isShowDelete){
            holder.img_delete.setVisibility(View.VISIBLE);
            if (position == 0){
                holder.img_delete.setVisibility(View.GONE);
            }
        }else {
            holder.img_delete.setVisibility(View.GONE);
        }
        holder.tv_content.setText(contentList.get(position));

        //删除
        holder.img_delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onItemDissmiss(holder);
            }
        });
    }

    @Override
    public int getItemCount() {
        return contentList.size();
    }

    @Override
    public void onItemMove(RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
        int fromPosition = source.getAdapterPosition();
        int toPosition = target.getAdapterPosition();
        if (fromPosition == 0 || toPosition == 0){//这个判断根据实际修改,可加可不加
            Toast.makeText(context,"第一个不可移动",Toast.LENGTH_SHORT).show();
        }else {
            if (fromPosition < contentList.size() && toPosition < contentList.size()) {
                //交换数据位置
                Collections.swap(contentList, fromPosition, toPosition);
                //刷新位置交换
                notifyItemMoved(fromPosition, toPosition);
            }
            //移动过程中移除view的放大效果
            onItemClear(source);
        }
    }

    @Override
    public void onItemDissmiss(RecyclerView.ViewHolder source) {
        int position = source.getAdapterPosition();
        contentList.remove(position); //移除数据
        notifyItemRemoved(position);//刷新数据移除
    }

    @Override
    public void onItemSelect(RecyclerView.ViewHolder source) {
        //当拖拽选中时放大选中的view
        source.itemView.setScaleX(1.2f);
        source.itemView.setScaleY(1.2f);
    }

    @Override
    public void onItemClear(RecyclerView.ViewHolder source) {
        //拖拽结束后恢复view的状态
        source.itemView.setScaleX(1.0f);
        source.itemView.setScaleY(1.0f);
    }

    public class DragHolder extends RecyclerView.ViewHolder {
        private final TextView tv_content;
        private final ImageView img_delete;//删除图标

        public DragHolder(View itemView) {
            super(itemView);
            tv_content = itemView.findViewById(R.id.tv_content);
            img_delete = itemView.findViewById(R.id.img_delete);
        }
    }

    public void setContentList(Context context, List<String> contentList,boolean isShowDelete){
        this.context = context;
        this.contentList = contentList;
        this.isShowDelete = isShowDelete;
        notifyDataSetChanged();
    }
}

4、item的布局文件  item_drag_recyclerview

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="@dimen/dimen_70dp"
    android:layout_height="@dimen/dimen_70dp"
    android:layout_margin="@dimen/dimen_10dp">

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="@dimen/dimen_60dp"
        android:layout_height="@dimen/dimen_60dp"
        android:text="1"
        android:textSize="@dimen/dimen_20dp"
        android:textColor="@color/text"
        android:textStyle="bold"
        android:gravity="center"
        android:background="@color/viewGray"
        android:layout_centerInParent="true"/>
    <ImageView
        android:id="@+id/img_delete"
        android:layout_width="@dimen/dimen_20dp"
        android:layout_height="@dimen/dimen_20dp"
        android:layout_alignParentRight="true"
        android:src="@mipmap/vibration_college_search_icon_empty"
        android:visibility="gone"/>

</RelativeLayout>

5、最后就是在我们的页面Activity中使用了,这里虚拟设置了20个数字

        setDragData();
        dragRecyclerView = findViewById(R.id.dragRecyclerView);
        //创建adapter
        dragRecyclerViewAdapter = new DragRecyclerViewAdapter(this, contentList);
        //设置默认的布局方式
        dragRecyclerView.setLayoutManager(new GridLayoutManager(this, 5,GridLayoutManager.VERTICAL, false));
        //设置adapter
        dragRecyclerView.setAdapter(dragRecyclerViewAdapter);
        //创建SimpleItemTouchHelperCallback
        ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(dragRecyclerViewAdapter);
        //用Callback构造ItemtouchHelper
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        //调用ItemTouchHelper的attachToRecyclerView方法建立联系
        touchHelper.attachToRecyclerView(dragRecyclerView);

        //编辑
        tv_edit = findViewById(R.id.tv_edit);
        tv_edit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (tv_edit.getText().toString().equals("编辑")){
                    tv_edit.setText("完成");
                    dragRecyclerViewAdapter.setContentList(SetTextColorActivity.this,contentList,true);
                }else {
                    tv_edit.setText("编辑");
                    dragRecyclerViewAdapter.setContentList(SetTextColorActivity.this,contentList,false);
                }
            }
        });

      private void setDragData(){
        for (int i = 1; i < 21; i++){
            contentList.add(i+"");
        }
      }

具体在项目中的实现需按实际需求来优化处理


版权声明:本文为u013184970原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。