当前位置: 移动技术网 > IT编程>移动开发>Android > Android实现可拖拽列表和多选功能

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

2019年09月06日  | 移动技术网IT编程  | 我要评论

中九接收机升级,八年级英语工作总结,冥神盛典

本文实例为大家分享了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里面的,其他难点注释里面都有,不懂的话要自己动手跑一下程序,然后也可以问我

效果如下图:

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网