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);
}
}