先看效果图
这是拖动前的图片
这是拖动列表改变位置后的图片
这里放上视频演示
RecyclerView实现列表拖动交换数据位置
主活动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); }}
主活动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>
适配器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; } @Override public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_recycler,viewGroup,false)); return holder; } @Override public void onBindViewHolder(MyViewHolder myViewHolder, @SuppressLint("RecyclerView") int position) { myViewHolder.tv_name.setText(list.get(position)); } @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); } }}
适配器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>
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); } @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; } @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { } @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); } @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)); } @Override public boolean isLongPressDragEnabled() { //开启长按后开始拖拽的效果 return true; } public interface RequestDouble<Integer1,Integer2> { void result(Integer1 integer1,Integer2 integer2); }}
来源地址:https://blog.csdn.net/qq_36570506/article/details/130446360