Android实现可拖拽列表和多选功能
程序员文章站
2022-11-22 22:05:16
本文实例为大家分享了android实现可拖拽列表和多选的具体代码,供大家参考,具体内容如下
这是我已经完成的一个已经上线的oa软件的一个模块,这个模块的功能不多,已经放到...
本文实例为大家分享了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利用RecyclerView实现全选、置顶和拖拽功能示例
-
Android开发实现ListView和adapter配合显示图片和文字列表功能示例
-
Android使用AlertDialog实现的信息列表单选、多选对话框功能
-
Android实现ListView控件的多选和全选功能实例
-
Android实现可拖拽列表和多选功能
-
Android利用RecyclerView实现全选、置顶和拖拽功能示例
-
Kotlin实战案例:带你实现RecyclerView分页查询功能(仿照主流电商APP,可切换列表和网格效果)
-
Android开发实现ListView和adapter配合显示图片和文字列表功能示例
-
Android实现ListView控件的多选和全选功能实例
-
Android 模仿QQ消息列表拖拽滑动和侧滑效果简单实现