服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android实现可拖拽列表和多选功能

Android实现可拖拽列表和多选功能

2022-10-24 13:52free5156 Android

这篇文章主要为大家详细介绍了Android实现可拖拽列表和多选功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android实现可拖拽列表和多选的具体代码,供大家参考,具体内容如下

这是我已经完成的一个已经上线的OA软件的一个模块,这个模块的功能不多,已经放到GitHub上面开源了,有感兴趣的朋友可以看看UIFrame

主窗口JAVA代码

?
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/**
 * 编辑状态下长按拖动条目
 * 1.通过ItemTouchHelper.Callback实现长按拖动
 * 2.通过isEditable的值判断是否编辑状态,初值是false
 * 3.切换编辑状态要把isEditable的值取反,并改变复选框图标状态
 * 4.在编辑状态下,按返回键回到非编辑状态
 * 5.RecyclerView的点击事件通过RecyclerAdapter.Callback实现
 */
 
public class ReportListActivity extends AppCompatActivity implements View.OnClickListener {
 
 private static final String TAG = "ReportListActivity";
 
 @BindView(R.id.tv_title_middle)
 TextView title;
 @BindView(R.id.title_left)
 ImageView backButton;
 @BindView(R.id.online_report_listview)
 RecyclerView mRecyclerView;
 @BindView(R.id.edit_tv)
 TextView edit;
 @BindView(R.id.filter_tv)
 TextView filter;
 @BindView(R.id.btn_delete)
 TextView delete;
 @BindView(R.id.btn_release)
 TextView release;
 @BindView(R.id.btn_close)
 TextView close;
 @BindView(R.id.btn_top)
 TextView top;
 @BindView(R.id.toolbar)
 LinearLayout mToolbar;
 
 private Context mContext;
 private boolean isEditable;
 private RecyclerAdapter mAdapter;
 private List<ClsOnlineReport> mClsOnlineReportList;
 private ItemTouchHelper itemTouchHelper;
 
 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_online_report);
  ButterKnife.bind(this);
 
  initView();
  initData();
  initListener();
 }
 
 private void initData() {
  mContext = this;
 
  mClsOnlineReportList = new ArrayList<>();
  mAdapter = new RecyclerAdapter(mClsOnlineReportList);
  mRecyclerView.setAdapter(mAdapter);
 
  getOfflineData(20);
 
  //初始状态为非编辑模式
  setIsEditable(false);
  //初始化拖动接口
  OnlineReportListCallback callback = new OnlineReportListCallback(mAdapter);
  itemTouchHelper = new ItemTouchHelper(callback);
 
  //初始状态为不可拖动
  setRecyclerViewDraggable(false);
 }
 
 //生成模拟数据
 private void getOfflineData(int num) {
  List<ClsOnlineReport> clsOnlineReportList = new ArrayList<>();
  for (int i = 0; i < num; i++) {
   ClsOnlineReport onlineReport = new ClsOnlineReport();
   onlineReport.setActiveDate("activeDate " + i);
   onlineReport.setAutoCloseDate("autoCloseDate " + i);
   onlineReport.setBulletinID("bulletinID " + i);
   onlineReport.setBulletinTime("bulletinTime " + i);
   onlineReport.setBulletinTitle("bulletinTitle " + i);
   onlineReport.setCreater("creater " + i);
   clsOnlineReportList.add(onlineReport);
  }
 
  mClsOnlineReportList.addAll(clsOnlineReportList);
  mAdapter.notifyDataSetChanged();
 }
 
 private void initView() {
  title.setText("可拖拽列表");
  edit.setVisibility(View.VISIBLE);
 
  mToolbar.setVisibility(View.GONE);
  //设置RecyclerView的布局
  mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
 }
 
 private void initListener() {
  filter.setOnClickListener(this);
  backButton.setOnClickListener(this);
  edit.setOnClickListener(this);
  delete.setOnClickListener(this);
  release.setOnClickListener(this);
  close.setOnClickListener(this);
  top.setOnClickListener(this);
 
 
  mAdapter.setmCallback((v, position) -> {
   switch (v.getId()) {
    case R.id.view_parent_1:
    case R.id.view_parent_2:
     ClsOnlineReport clsOnlineReport = mClsOnlineReportList.get(position);
 
     //在编辑模式下,点击条目切换显示checkbox,并且判断选中条目的数量,
     if (getIsEditable()) {
      if (clsOnlineReport.getIsCheckBoxVisible()) {
       clsOnlineReport.setIsChecked(!clsOnlineReport.getIsChecked());
       mAdapter.notifyDataSetChanged();
      }
 
      for (int i = 0; i < mClsOnlineReportList.size(); i++) {
       //数量等于0,隐藏工具条,否则显示工具条
       ClsOnlineReport onlineReport = mClsOnlineReportList.get(i);
       if (onlineReport.getIsChecked()) {
        mToolbar.setVisibility(View.VISIBLE);
        break;
       }
       if (i == mClsOnlineReportList.size() - 1) {
        mToolbar.setVisibility(View.GONE);
       }
      }
     } else {
      //在非编辑模式下,点击条目直接跳转详情页,并把bulletinID传过去
      Intent intent = new Intent(mContext, ReportDetailActivity.class);
      intent.putExtra("bulletinID", clsOnlineReport.getBulletinID());
      startActivityForResult(intent, 16371);
     }
   }
  });
 }
 
 @Override
 public void onBackPressed() {
  //编辑状态下,按返回键回到非编辑状态,否则退出
  if (getIsEditable()) {
   switchEditable();
  } else {
   finish();
  }
 }
 
 @Override
 public void onClick(View v) {
  //编辑状态下,按返回键回到非编辑状态,否则退出
  if (v.getId() == R.id.title_left) {
   if (getIsEditable()) {
    switchEditable();
   } else {
    finish();
   }
  }
  //点击编辑按钮切换编辑状态
  if (v.getId() == R.id.edit_tv) {
   switchEditable();
  }
 
  //工具条的按钮对应不同的接口
  switch (v.getId()) {
   case R.id.btn_top:
   case R.id.btn_close:
   case R.id.btn_release:
   case R.id.btn_delete:
    Toast.makeText(mContext, "在此处调用接口", Toast.LENGTH_SHORT).show();
  }
 
 }
 
 private void switchEditable() {
 
  //将属性取反
  setIsEditable(!getIsEditable());
 
  //遍历列表并赋值
  for (ClsOnlineReport clsOnlineReport : mClsOnlineReportList) {
   clsOnlineReport.setIsCheckBoxVisible(getIsEditable());
   clsOnlineReport.setIsChecked(false);
  }
 
  //通知适配器刷新
  mAdapter.notifyDataSetChanged();
  //隐藏工具条
  mToolbar.setVisibility(View.GONE);
  //切换拖动状态
  setRecyclerViewDraggable(getIsEditable());
 }
 
 public boolean getIsEditable() {
  return isEditable;
 }
 
 public void setIsEditable(boolean isEditable) {
  this.isEditable = isEditable;
 }
 
 //设置能否拖动
 private void setRecyclerViewDraggable(boolean draggable) {
  if (draggable) {
   itemTouchHelper.attachToRecyclerView(mRecyclerView);
  } else {
   itemTouchHelper.attachToRecyclerView(null);
  }
 }
 
 @Override
 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
 
  //当详情页的数据有变动则刷新列表
  if (requestCode == 16371 && resultCode == RESULT_OK) {
   refreshData();
  }
 
  super.onActivityResult(requestCode, resultCode, data);
 }
 
 private void refreshData() {
  Toast.makeText(mContext, "在此处调用接口", Toast.LENGTH_SHORT).show();
 }
}

适配器代码

?
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
/**
 * 可拖拽列表的适配器,
 * 1.需要实现OnlineReportListCallback.ItemTouchMoveListener
 * 2.持有一个接口用于传递position
 */
public class RecyclerAdapter extends RecyclerView.Adapter implements OnlineReportListCallback.ItemTouchMoveListener, View.OnClickListener {
 
 private List<ClsOnlineReport> mList;
 private Callback mCallback;
 
 public RecyclerAdapter(List<ClsOnlineReport> mList) {
  this.mList = mList;
 }
 
 public void setmCallback(Callback mCallback) {
  this.mCallback = mCallback;
 }
 
 @Override
 public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 
  LayoutInflater inflater = LayoutInflater.from(parent.getContext());
  View v = inflater.inflate(R.layout.item_report_list, parent, false);
  return new ItemHolder(v);
 }
 
 @Override
 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
 
  ClsOnlineReport clsOnlineReport = mList.get(position);
  ItemHolder itemHolder = (ItemHolder) holder;
 
  if (clsOnlineReport.getIsCheckBoxVisible()) {
   itemHolder.checkbox.setVisibility(View.VISIBLE);
   itemHolder.drag.setVisibility(View.VISIBLE);
  } else {
   itemHolder.checkbox.setVisibility(View.GONE);
   itemHolder.drag.setVisibility(View.GONE);
  }
 
  if (clsOnlineReport.getIsChecked()) {
   itemHolder.checkbox.setImageResource(R.drawable.ic_check_box_black_24dp);
  } else {
   itemHolder.checkbox.setImageResource(R.drawable.ic_check_box_outline_blank_black_24dp);
  }
 
  itemHolder.parent1.setTag(position);
  itemHolder.parent2.setTag(position);
 
  itemHolder.parent1.setOnClickListener(this);
  itemHolder.parent2.setOnClickListener(this);
 
  itemHolder.time.setText(clsOnlineReport.getBulletinTime());
  itemHolder.title.setText(clsOnlineReport.getBulletinTitle());
  itemHolder.author.setText(clsOnlineReport.getCreater());
 }
 
 @Override
 public int getItemCount() {
  return mList.size();
 }
 
 @Override
 public boolean onItemMove(int fromPosition, int toPosition) {
  Collections.swap(mList, fromPosition, toPosition);
  notifyItemMoved(fromPosition, toPosition);
  return true;
 }
 
 class ItemHolder extends RecyclerView.ViewHolder {
 
  @BindView(R.id.online_report_time)
  TextView time;
  @BindView(R.id.online_report_title)
  TextView title;
  @BindView(R.id.online_report_author)
  TextView author;
  @BindView(R.id.online_report_drag)
  ImageView drag;
  @BindView(R.id.online_report_checkbox)
  ImageView checkbox;
  @BindView(R.id.view_parent_1)
  LinearLayout parent1;
  @BindView(R.id.view_parent_2)
  LinearLayout parent2;
 
  ItemHolder(View itemView) {
   super(itemView);
   ButterKnife.bind(this, itemView);
  }
 }
 
 @Override
 public void onClick(View v) {
  mCallback.onClick(v, (int) v.getTag());
 }
 
 public interface Callback {
  void onClick(View v, int position);
 }
}

需要实现的接口

?
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
/**
 * 用来完成RecyclerView长按拖拽的关键接口
 * 1.getMovementFlags里面表示设置为上下拖动
 * 2.onSelectedChanged里面表示拖动状态下改变背景色,拖动完成后恢复背景色
 * 3.拖动完成的时候viewHolder的值为空!!!所以要用srcHolder
 */
public class OnlineReportListCallback extends ItemTouchHelper.Callback {
 
 private ColorDrawable drawable;
 private RecyclerView.ViewHolder srcHolder;
 
 public interface ItemTouchMoveListener {
  boolean onItemMove(int fromPosition, int toPosition);
 }
 
 private ItemTouchMoveListener moveListener;
 
 public OnlineReportListCallback(ItemTouchMoveListener moveListener) {
  this.moveListener = moveListener;
 
  int rgb = Color.rgb(0xff, 0xff, 0xff);
  drawable = new ColorDrawable(rgb);
 }
 
 
 @Override
 public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
 
  int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
  return makeMovementFlags(dragFlags, ItemTouchHelper.ACTION_STATE_IDLE);
 }
 
 @Override
 public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder srcHolder, RecyclerView.ViewHolder targetHolder) {
 
  this.srcHolder = srcHolder;
  return srcHolder.getItemViewType() == targetHolder.getItemViewType() && moveListener.onItemMove(srcHolder.getAdapterPosition(), targetHolder.getAdapterPosition());
 }
 
 @Override
 public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
 
 }
 
 @Override
 public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
 
  super.onSelectedChanged(viewHolder, actionState);
 
  if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
   viewHolder.itemView.setBackground(null);
  }
 
  if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) {
   srcHolder.itemView.setBackground(drawable);
  }
 }
}

图片使用Android Studio内置的SVG,引入了ButterKnife绑定控件,另外内部类使用了lambda表达式折叠了,重点说一下RecyclerAdapter.Callback,这个接口的内部方法 void onClick(View v, int position) 是在View.OnClickListener的
void onClick(View v)的基础上多传了一个参数,这个参数是放在tag里面的,其他难点注释里面都有,不懂的话要自己动手跑一下程序,然后也可以问我

效果如下图:

Android实现可拖拽列表和多选功能

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

原文链接:https://blog.csdn.net/csdncaoguo940713/article/details/89965873

延伸 · 阅读

精彩推荐