RecyclerView实现拖拽排序效果

时间:2022-06-01 22:14:44

效果就是这样,RecyclerView列表可拖拽排序,可删除,可添加;

RecyclerView实现拖拽排序效果

RecyclerView给我们提供了一个手势器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
  @Override
  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
   int dragFrlg = 0;
   if (recyclerView.getLayoutManager() instanceof GridLayoutManager){
    dragFrlg = ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
   }else if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){
    dragFrlg = ItemTouchHelper.UP|ItemTouchHelper.DOWN;
   }
   return makeMovementFlags(dragFrlg,0);
  }
 
  @Override
  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
   //滑动事件 下面注释的代码,滑动后数据和条目错乱,被舍弃
//   Collections.swap(datas,viewHolder.getAdapterPosition(),target.getAdapterPosition());
//   ap.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
 
   //得到当拖拽的viewHolder的Position
   int fromPosition = viewHolder.getAdapterPosition();
   //拿到当前拖拽到的item的viewHolder
   int toPosition = target.getAdapterPosition();
   if (fromPosition < toPosition) {
    for (int i = fromPosition; i < toPosition; i++) {
     Collections.swap(datas, i, i + 1);
    }
   } else {
    for (int i = fromPosition; i > toPosition; i--) {
     Collections.swap(datas, i, i - 1);
    }
   }
   ap.notifyItemMoved(fromPosition, toPosition);
   return true;
  }
 
  @Override
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    //侧滑删除可以使用;
  }
 
  @Override
  public boolean isLongPressDragEnabled() {
   return true;
  }
  /**
   * 长按选中Item的时候开始调用
   * 长按高亮
   * @param viewHolder
   * @param actionState
   */
  @Override
  public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
   if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
    viewHolder.itemView.setBackgroundColor(Color.RED);
    //获取系统震动服务//震动70毫秒
    Vibrator vib = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
    vib.vibrate(70);
   }
   super.onSelectedChanged(viewHolder, actionState);
  }
 
  /**
   * 手指松开的时候还原高亮
   * @param recyclerView
   * @param viewHolder
   */
  @Override
  public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
   super.clearView(recyclerView, viewHolder);
   viewHolder.itemView.setBackgroundColor(0);
   ap.notifyDataSetChanged(); //完成拖动后刷新适配器,这样拖动后删除就不会错乱
  }
 });

设置给RecyclerView即可:

?
1
helper.attachToRecyclerView(rv);

下面是完整的代码和Xml布局文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 private final String TAG = this.getClass().getSimpleName();
 private List<String> d = Arrays.asList(
   "A","B","C","D","E","F","G"
   ,"H","I","J","K","L","M","N"
   ,"O","P","Q","R","S","T"
   ,"U","V","W","X","Y","Z");
 private RecyclerView rv ;
 private Ap<String> ap;
 private List<String> datas;
 private EditText edAdd;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  initData();
  rv = findViewById(R.id.rv);
  edAdd =findViewById(R.id.et_add);
  rv.setLayoutManager(new GridLayoutManager(this,3));
//  rv.setLayoutManager(new LinearLayoutManager(this));
  ap = new Ap(this, datas);
  rv.setAdapter(ap);
  helper.attachToRecyclerView(rv);
  findViewById(R.id.tv).setOnClickListener(this);
  findViewById(R.id.tv_add).setOnClickListener(this);
 }
 
 private void initData() {
  datas = new ArrayList<>();
//  直接用d操作集合会崩溃,Arrays.asList集合不可增删改;详细可以看我的博客
  for (int i = 0; i < d.size(); i++) {
   datas.add(d.get(i));
  }
 }
 
 @Override
 public void onClick(View view) {
  switch (view.getId()){
   case R.id.tv:
    for (int i = 0; i < datas.size(); i++) {
     Log.i(TAG, "onClick: ____"+datas.get(i));
    }
    break;
   case R.id.tv_add:
    ap.add(edAdd.getText().toString().trim());
    edAdd.setText(null);
    break;
  }
 }
 
 
 class Ap<T> extends RecyclerView.Adapter<Ap.Vh>{
  private Context context;
  public List<T> stringList;
  public Ap(Context context, List<T> stringList) {
   this.context = context;
   this.stringList = stringList;
  }
 
  @Override
  public Ap.Vh onCreateViewHolder(ViewGroup parent, int viewType) {
   return new Vh(LayoutInflater.from(context).inflate(R.layout.item_rv,null));
  }
 
  @Override
  public void onBindViewHolder(Ap.Vh holder, final int position) {
   holder.tv.setText(stringList.get(position).toString());
   holder.iv.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
     remove(position);
    }
   });
  }
 
  @Override
  public int getItemCount() {
   return stringList.size();
  }
 
  public void add(T item){
   int position = stringList.size();
   stringList.add(item);
   notifyItemInserted(position);
  }
 
  public void add(int position,T item){
   stringList.add(position,item);
   notifyItemInserted(position);
  }
//  public void remove(T item) {
//   final int position = stringList.indexOf(item);
//   if (-1 == position)
//    return;
//   stringList.remove(item);
//   notifyItemRemoved(position);
//  }
 
  public void remove(int position) {
   stringList.remove(position);
   notifyItemRemoved(position);
   notifyItemRangeChanged(position,stringList.size());
  }
 
  class Vh extends RecyclerView.ViewHolder {
 
   public Vh(View itemView) {
    super(itemView);
    tv = itemView.findViewById(R.id.tv);
    iv = itemView.findViewById(R.id.iv_delete);
   }
   public TextView tv;
   public ImageView iv;
  }
 }
 
 ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
  @Override
  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
   int dragFrlg = 0;
   if (recyclerView.getLayoutManager() instanceof GridLayoutManager){
    dragFrlg = ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
   }else if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){
    dragFrlg = ItemTouchHelper.UP|ItemTouchHelper.DOWN;
   }
   return makeMovementFlags(dragFrlg,0);
  }
 
  @Override
  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
   //滑动事件 下面注释的代码,滑动后数据和条目错乱,被舍弃
//   Collections.swap(datas,viewHolder.getAdapterPosition(),target.getAdapterPosition());
//   ap.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
 
   //得到当拖拽的viewHolder的Position
   int fromPosition = viewHolder.getAdapterPosition();
   //拿到当前拖拽到的item的viewHolder
   int toPosition = target.getAdapterPosition();
   if (fromPosition < toPosition) {
    for (int i = fromPosition; i < toPosition; i++) {
     Collections.swap(datas, i, i + 1);
    }
   } else {
    for (int i = fromPosition; i > toPosition; i--) {
     Collections.swap(datas, i, i - 1);
    }
   }
   ap.notifyItemMoved(fromPosition, toPosition);
   return true;
  }
 
  @Override
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    //侧滑删除可以使用;
  }
 
  @Override
  public boolean isLongPressDragEnabled() {
   return true;
  }
  /**
   * 长按选中Item的时候开始调用
   * 长按高亮
   * @param viewHolder
   * @param actionState
   */
  @Override
  public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
   if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
    viewHolder.itemView.setBackgroundColor(Color.RED);
    //获取系统震动服务//震动70毫秒
    Vibrator vib = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
    vib.vibrate(70);
   }
   super.onSelectedChanged(viewHolder, actionState);
  }
 
  /**
   * 手指松开的时候还原高亮
   * @param recyclerView
   * @param viewHolder
   */
  @Override
  public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
   super.clearView(recyclerView, viewHolder);
   viewHolder.itemView.setBackgroundColor(0);
   ap.notifyDataSetChanged(); //完成拖动后刷新适配器,这样拖动后删除就不会错乱
  }
 });
}

Xml布局文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?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"
 tools:context="com.ccb.pactera.dragrecyclerviewdemo.MainActivity">
 
 <LinearLayout
  android:id="@+id/ll"
  android:background="#eeeeee"
  android:orientation="horizontal"
  android:layout_width="match_parent"
  android:layout_height="48dp">
  <TextView
   android:layout_width="0dp"
   android:layout_weight="1"
   android:layout_height="48dp"
   android:id="@+id/tv"
   android:text="查看数据"
   android:textColor="#fff"
   android:textSize="16dp"
   android:gravity="center"
   android:background="@color/colorAccent"
   />
  <EditText
   android:id="@+id/et_add"
   android:layout_width="0dp"
   android:layout_height="match_parent"
   android:layout_weight="1"/>
  <TextView
   android:layout_width="0dp"
   android:layout_weight="1"
   android:layout_height="48dp"
   android:id="@+id/tv_add"
   android:text="添加数据"
   android:textColor="#fff"
   android:textSize="16dp"
   android:gravity="center"
   android:background="#fc1"
   />
 </LinearLayout>
 <android.support.v7.widget.RecyclerView
  android:id="@+id/rv"
  android:layout_below="@id/ll"
  android:layout_width="match_parent"
  android:layout_height="match_parent" />
 
</RelativeLayout>

RecyclerView的Item:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:background="#f1f1f1"
 android:layout_height="match_parent">
 <RelativeLayout
  android:layout_width="match_parent"
  android:background="#fff"
  android:layout_margin="0.5dp"
  android:layout_height="match_parent">
 <ImageView
  android:layout_width="match_parent"
  android:layout_height="50dp"
  android:src="@mipmap/icon"
  android:id="@+id/iv"
  android:layout_marginTop="10dp"
  />
<TextView
 android:id="@+id/tv"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:textSize="16dp"
 android:layout_below="@id/iv"
 android:gravity="center_horizontal"
 android:layout_marginBottom="10dp"
 />
 <ImageView
  android:layout_width="25dp"
  android:layout_height="25dp"
  android:layout_alignParentRight="true"
  android:src="@mipmap/detele"
  android:id="@+id/iv_delete"
  />
 </RelativeLayout>
</RelativeLayout>

资源链接Github

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_35605213/article/details/80541461