Android实现可拖拽列表和多选功能
时间:2020-10-24 21:40:54|栏目:Android代码|点击: 次
本文实例为大家分享了Android实现可拖拽列表和多选的具体代码,供大家参考,具体内容如下
这是我已经完成的一个已经上线的OA软件的一个模块,这个模块的功能不多,已经放到GitHub上面开源了,有感兴趣的朋友可以看看UIFrame
主窗口JAVA代码
/** * 编辑状态下长按拖动条目 * 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.需要实现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); } }
需要实现的接口
/** * 用来完成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中AsyncTask与handler用法实例分析
栏 目:Android代码
下一篇:Activity生命周期实例讲解
本文标题:Android实现可拖拽列表和多选功能
本文地址:http://www.codeinn.net/misctech/15481.html