Android的RecyclerView实现列表拖动(移动顺序)交换数据位置

1.先看效果图
这是拖动前的图片
在这里插入图片描述
这是拖动列表改变位置后的图片
在这里插入图片描述
这里放上视频演示

RecyclerView实现列表拖动交换数据位置

2.主活动MainActivity2类代码如下

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.annotation.SuppressLint;
import android.os.Bundle;
import com.example.myapplication001.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MainActivity2 extends AppCompatActivity {
    
    

    private HomeAdapter rv_1_homeAdapter;
    RecyclerView rv_1;
    LinearLayoutManager rv_1_Manager;
    ItemTouchHelper mItemTouchHelper;
    List<String> titles;

    @SuppressLint({
    
    "MissingInflatedId", "WrongViewCast"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        rv_1=findViewById(R.id.rv_1);

        titles = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
    
    
            titles.add("中文"+i);
        }


        rv_1_homeAdapter = new HomeAdapter(getApplicationContext(),titles);
        rv_1_Manager=new LinearLayoutManager(getApplicationContext());
        //这里使用垂直滑动
        rv_1_Manager.setOrientation(LinearLayoutManager.VERTICAL);
        rv_1.setLayoutManager(rv_1_Manager);
        rv_1.setAdapter(rv_1_homeAdapter);

        //添加拖拽事件                                                                 longClickPosition:初始索引值            ActionUpPosition:结束索引值
        mItemTouchHelper = new ItemTouchHelper(new MyItemTouchHelper(this,titles,rv_1_homeAdapter,(longClickPosition, ActionUpPosition)-> {
    
    
            if (longClickPosition==-1)return;

            //用swap方法可以交换集合中任意两个元素的位置
            Collections.swap(titles,longClickPosition,ActionUpPosition);

            //列表的适配器
            rv_1_homeAdapter.notifyDataSetChanged();

        }));
        //在这里给列表添加移动顺序
        mItemTouchHelper.attachToRecyclerView(rv_1);
    }

}

3.主活动MainActivity2类activity_main2的布局代码如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/refreshLa"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>


</LinearLayout>

4.适配器HomeAdapter类代码如下

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication001.R;
import java.util.List;

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>{
    
    

    private Context mContext;
    List<String> list;

    public HomeAdapter(Context mContext, List<String> list) {
    
    
        this.mContext = mContext;
        this.list=list;
    }

    /**
     * 设置布局
     * @param viewGroup
     * @param i
     * @return
     */
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    
    
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_recycler,viewGroup,false));
        return holder;
    }

    /**
     * 为控件绑定数据
     * @param myViewHolder
     * @param position
     */
    @Override
    public void onBindViewHolder(MyViewHolder myViewHolder, @SuppressLint("RecyclerView") int position) {
    
    

        myViewHolder.tv_name.setText(list.get(position));

    }

    /**
     * 返回项个数
     * @return
     */
    @Override
    public int getItemCount() {
    
    
        return list.size();
    }

    /**
     * 定义控件并初始化
     */
    class MyViewHolder extends RecyclerView.ViewHolder{
    
    

        TextView tv_name;

        public MyViewHolder(View itemView) {
    
    
            super(itemView);
            tv_name = itemView.findViewById(R.id.tv_name);
        }
    }
}

5.适配器HomeAdapter类的item_recycler布局代码如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="10dp"
            android:text="name"
            android:textColor="@color/black" />

    </LinearLayout>

    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#E1DFDF" />
</LinearLayout>

6.MyItemTouchHelper类代码如下

import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class MyItemTouchHelper extends ItemTouchHelper.Callback{
    
    
    private List<String> list;
    private HomeAdapter recycleViewAdapter;
    private RequestDouble<Integer,Integer> mRequestResult;
    private int longClickPosition=-1;
    MainActivity2 activity;
    public MyItemTouchHelper(MainActivity2 activity, List<String> list, HomeAdapter recycleViewAdapter,RequestDouble<Integer,Integer> requestResult) {
    
    
        Log.d("dddd","into MyItemTouchHelper");
        this.list = list;
        this.recycleViewAdapter = recycleViewAdapter;
        this.activity = activity;
        this.mRequestResult=requestResult;
    }

    //设置拖拽和item滑动的可支持方向
    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
    
    
        //这里是设置列表水平拖动
     //   final int dragFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;  //ItemTouchHelper.UP | ItemTouchHelper.DOWN |
        //这里是设置列表是垂直拖动
        final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;  //ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT |

        //这里是设置网格布局拖动
     //   final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;

        final int swipeFlags = 0;
        return makeMovementFlags(dragFlags, swipeFlags);
    }


    /**
     * 拖拽结束后(手指抬起)会回调的方法
     *
     * @param recyclerView
     * @param viewHolder 手指拖拽的item
     * @param target 移动到的item
     * @return
     */
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
    
    
        // 我们在该方法中实现item数据在数据集合中的位置交换,并调用Adapter的notifyItemMoved完成item界面刷新
        recyclerView.getParent().requestDisallowInterceptTouchEvent(true);
        //得到当拖拽的viewHolder的Position
        int fromPosition = viewHolder.getAdapterPosition();
        //拿到当前拖拽到的item的viewHolder
        int toPosition = target.getAdapterPosition();
        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, i - 1);
            }
        }
        int movementFlags = getMovementFlags(recyclerView, viewHolder);
        Log.d("dddd============="," movementFlags = "+movementFlags);
        //通知适配器改变位置
        recycleViewAdapter.notifyItemMoved(fromPosition, toPosition);
        Log.d("dddd============="," fromPosition = "+fromPosition+" toPosition"+toPosition);
        return true;
    }

    /**
     * 侧滑回调
     *
     * @param viewHolder
     * @param direction 方向
     */
    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
    
    

    }

    /**
     * 长按选中Item时修改颜色
     *
     * @param viewHolder
     * @param actionState
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
    
    
        //if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
    
    
        //viewHolder.itemView.setBackground(getDrawable(R.drawable.card_drag_selected));
        //}
        if (viewHolder!=null){
    
    
            longClickPosition= viewHolder.getAdapterPosition();
            Log.d("adapterPosition=====","adapterPosition22222="+longClickPosition);
        }

        super.onSelectedChanged(viewHolder, actionState);
    }

    /**
     * 手指松开的时候还原颜色
     * @param recyclerView
     * @param viewHolder
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    
    
        int adapterPosition = viewHolder.getAdapterPosition();
        if (mRequestResult!=null){
    
    
            //longClickPosition:这是初始索引值            adapterPosition:这是结束索引值
            mRequestResult.result(longClickPosition,adapterPosition);
        }
        Log.d("adapterPosition=====","adapterPosition="+adapterPosition);
        super.clearView(recyclerView, viewHolder);
        //viewHolder.itemView.setBackground(getDrawable(R.drawable.card));
    }

    /**
     * 重写拖拽不可用
     * @return
     */
    @Override
    public boolean isLongPressDragEnabled() {
    
    
        //开启长按后开始拖拽的效果
        return true;
    }

    public interface RequestDouble<Integer1,Integer2> {
    
    
        void result(Integer1 integer1,Integer2 integer2);

    }

}

猜你喜欢

转载自blog.csdn.net/qq_36570506/article/details/130446360