欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-05-14 15:25:34
本文实例为大家分享了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实现可拖拽列表和多选功能

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