简介
使用RecyclerView和ItemTouchHelper可以方便地实现Item的拖拽排序,以下为实现效果:
代码实现
主页面xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
android:background="@mipmap/drag_page"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/drag_device_return"
android:layout_width="40dp"
android:layout_height="40dp"
android:onClick="onReturnClick">
<ImageView
android:id="@+id/drag_return"
android:layout_width="9dp"
android:layout_height="16dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@mipmap/return_button"
>
</ImageView>
</RelativeLayout>
<TextView
android:id="@+id/drag_tv"
android:layout_width="72dp"
android:layout_height="27dp"
android:layout_marginLeft="35dp"
android:layout_marginTop="16dp"
android:text="拖动排序"
android:textColor="#FFFFFFFF"
android:textSize="18sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/drag_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
>
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
Item的xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="192dp"
android:layout_height="110dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
xmlns:tools="http://schemas.android.com/tools">
<RelativeLayout
android:id="@+id/drag_device_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/card">
<TextView
android:id="@+id/drag_tv2"
android:text="洗衣机"
android:layout_width="48dp"
android:layout_height="23dp"
android:layout_marginLeft="12dp"
android:layout_marginTop="12dp"
android:textColor="#FFFFFFFF"
android:gravity="center"
android:textSize="16sp"
android:fontFamily="SourceHanSansCN"/>
<ImageView
android:id="@+id/drag_button"
android:layout_width="13dp"
android:layout_height="10dp"
android:layout_marginLeft="166dp"
android:layout_marginTop="15dp"
android:src="@mipmap/drag_button"
>
</ImageView>
</RelativeLayout>
</RelativeLayout>
MainActivity代码
此处使用GridLayoutManager实现列布局,注意不能使用StaggeredGridLayoutManager,拖动第一个Item会导致显示异常:
package com.example.recycleviewtest;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private List<String> list;
private MyAdapter myAdapter;
private ItemTouchHelper mItemTouchHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.drag_rv);
initView();
initData();
}
//点击返回按钮时返回
public void onReturnClick(View view) {
finish();
}
private void initView() {
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
mRecyclerView.setLayoutManager(gridLayoutManager);
mRecyclerView.setNestedScrollingEnabled(false);
}
private void initData() {
list = new ArrayList<>() ;
list.add("洗衣机");
list.add("空调");
list.add("风扇");
list.add("净水器");
list.add("洗碗机");
list.add("加湿器");
mRecyclerView.setAdapter(myAdapter = new MyAdapter());
mItemTouchHelper = new ItemTouchHelper(new MyItemTouchHelper());
mItemTouchHelper.attachToRecyclerView(mRecyclerView);
}
public class MyItemTouchHelper extends ItemTouchHelper.Callback {
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
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) {
//得到当拖拽的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);
}
}
myAdapter.notifyItemMoved(fromPosition, toPosition);
return true;
}
@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));
//}
super.onSelectedChanged(viewHolder, actionState);
}
/**
* 手指松开的时候还原颜色
* @param recyclerView
* @param viewHolder
*/
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
//viewHolder.itemView.setBackground(getDrawable(R.drawable.card));
}
/**
* 重写拖拽不可用
* @return
*/
@Override
public boolean isLongPressDragEnabled() {
return true;
}
}
class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
public MyAdapter() {
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_drag_device, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.deviceName.setText(list.get(position));
}
@Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView deviceName;
public ViewHolder(View itemView) {
super(itemView);
deviceName = itemView.findViewById(R.id.drag_tv2);
}
}
}
}