登录 立即注册
安币:
查看: 126|回复: 6
打印 上一主题 下一主题

重庆时时彩倍投技巧| android RecyclerView实现条目Item拖拽排序与滑动删除

[复制链接]

196

主题

196

帖子

443

安币

手工艺人

跳转到指定楼层
楼主
发表于 2017-12-5 10:36:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文来源:http://www.oneupabq.com/a/www.chekb.com/

重庆时时彩独胆倍投 www.oneupabq.com,清热凉血莲藕生用性寒,有清热凉血作用,可用来治疗热性病症;莲藕味甘多液、对热病口渴、衄血、咯血、下血者尤为有益。调治疮肿误治、毒气入肺:笋尖、、各25g,沙参、、贝母各15g,1条。


        效果演示

        

        需求和技术分析



  

    1. recyclerview item拖拽排序::长按recyclerview的item或者触摸item的某个按钮。


  

    2. recyclerview item滑动删除:recyclerview item滑动删除:recyclerview的item滑动删除。

        实现方案与技术

        利用itemtouchhelper绑定recyclerview、itemtouchhelper.callback来实现ui更新,并且实现动态控制是否开启拖拽功能和滑动删除功能。

        实现步骤



  

    1. 继承抽象类itemtouchhelper,并在构造方法传入实现的itemtouchhelper.callback。


  

    2. recyclerview绑定itemtouchhelper:itemtouchhelper.attachtorecyclerview(recyclerview)。


  

    3. 自定义itemtouchhelper.callback的实现接口onitemtouchcallbacklistener,由外部更新recyclerview的item。
  

        几个主要的布局

        activity_main.xml

[Java] 查看源文件 复制代码
<

        这个没啥好说的了吧,就是一个recyclerview啦。

        接下来是recyclerview的item的布局item.xml:

[Java] 查看源文件 复制代码
<

        这个也不用解释了,到时候下载看源码,就是普通item,展示数据而已。

        实现自己的defaultitemtouchhelper:继承itemtouchhelper

[Java] 查看源文件 复制代码
public class defaultitemtouchhelper extends itemtouchhelper {
  public defaultitemtouchhelper(itemtouchhelp.callback callback) {
    super(callback);
  }
}

        好嘛,这个太简单了,基本上一行代码都不用写。但是这里需要一个itemtouchhelp.callback啊,所以我们还是要实现一个itemtouchhelp.callback,客观且看下文分解。

        实现自己的itemtouchhelper.callback:继承itemtouchhelper.callback

        这里是全文最重要的部分啦,要认真点看噢,先上代码,后解释,其他看注释和视频。

[Java] 查看源文件 复制代码
public class defaultitemtouchhelpcallback extends itemtouchhelper.callback {

  /**
   * item操作的回调
   */
  private onitemtouchcallbacklistener onitemtouchcallbacklistener;

  /**
   * 是否可以拖拽
   */
  private boolean iscandrag = false;
  /**
   * 是否可以被滑动
   */
  private boolean iscanswipe = false;

  public defaultitemtouchhelpcallback(onitemtouchcallbacklistener onitemtouchcallbacklistener) {
    this.onitemtouchcallbacklistener = onitemtouchcallbacklistener;
  }

  /**
   * 设置item操作的回调,去更新ui和数据源
   *
   * @param onitemtouchcallbacklistener
   */
  public void setonitemtouchcallbacklistener(onitemtouchcallbacklistener onitemtouchcallbacklistener) {
    this.onitemtouchcallbacklistener = onitemtouchcallbacklistener;
  }

  /**
   * 设置是否可以被拖拽
   *
   * @param candrag 是true,否false
   */
  public void setdragenable(boolean candrag) {
    iscandrag = candrag;
  }

  /**
   * 设置是否可以被滑动
   *
   * @param canswipe 是true,否false
   */
  public void setswipeenable(boolean canswipe) {
    iscanswipe = canswipe;
  }

  /**
   * 当item被长按的时候是否可以被拖拽
   *
   * @return
   */
  @override
  public boolean islongpressdragenabled() {
    return iscandrag;
  }

  /**
   * item是否可以被滑动(h:左右滑动,v:上下滑动)
   *
   * @return
   */
  @override
  public boolean isitemviewswipeenabled() {
    return iscanswipe;
  }

  /**
   * 当用户拖拽或者滑动item的时候需要我们告诉系统滑动或者拖拽的方向
   *
   * @param recyclerview
   * @param viewholder
   * @return
   */
  @override
  public int getmovementflags(recyclerview recyclerview, recyclerview.viewholder viewholder) {
    recyclerview.layoutmanager layoutmanager = recyclerview.getlayoutmanager();
    if (layoutmanager instanceof gridlayoutmanager) {// gridlayoutmanager
      // flag如果值是0,相当于这个功能被关闭
      int dragflag = itemtouchhelper.left | itemtouchhelper.right | itemtouchhelper.up | itemtouchhelper.down;
      int swipeflag = 0;
      // create make
      return makemovementflags(dragflag, swipeflag);
    } else if (layoutmanager instanceof linearlayoutmanager) {// linearlayoutmanager
      linearlayoutmanager linearlayoutmanager = (linearlayoutmanager) layoutmanager;
      int orientation = linearlayoutmanager.getorientation();

      int dragflag = 0;
      int swipeflag = 0;

      // 为了方便理解,相当于分为横着的listview和竖着的listview
      if (orientation == linearlayoutmanager.horizontal) {// 如果是横向的布局
        swipeflag = itemtouchhelper.up | itemtouchhelper.down;
        dragflag = itemtouchhelper.left | itemtouchhelper.right;
      } else if (orientation == linearlayoutmanager.vertical) {// 如果是竖向的布局,相当于listview
        dragflag = itemtouchhelper.up | itemtouchhelper.down;
        swipeflag = itemtouchhelper.left | itemtouchhelper.right;
      }
      return makemovementflags(dragflag, swipeflag);
    }
    return 0;
  }

  /**
   * 当item被拖拽的时候被回调
   *
   * @param recyclerview   recyclerview
   * @param srcviewholder  拖拽的viewholder
   * @param targetviewholder 目的地的viewholder
   * @return
   */
  @override
  public boolean onmove(recyclerview recyclerview, viewholder srcviewholder, viewholder targetviewholder) {
    if (onitemtouchcallbacklistener != null) {
      return onitemtouchcallbacklistener.onmove(srcviewholder.getadapterposition(), targetviewholder.getadapterposition());
    }
    return false;
  }

  @override
  public void onswiped(viewholder viewholder, int direction) {
    if (onitemtouchcallbacklistener != null) {
      onitemtouchcallbacklistener.onswiped(viewholder.getadapterposition());
    }
  }

  public interface onitemtouchcallbacklistener {
    /**
     * 当某个item被滑动删除的时候
     *
     * @param adapterposition item的position
     */
    void onswiped(int adapterposition);

    /**
     * 当两个item位置互换的时候被回调
     *
     * @param srcposition  拖拽的item的position
     * @param targetposition 目的地的item的position
     * @return 开发者处理了操作应该返回true,开发者没有处理就返回false
     */
    boolean onmove(int srcposition, int targetposition);
  }
}

        好,其实上面最重要的就是五个方法:

[Java] 查看源文件 复制代码
/**
 * 是否可以长按拖拽排序。
 */
@override
public boolean islongpressdragenabled() {}
/**
 * item是否可以被滑动(h:左右滑动,v:上下滑动)
 */
@override
public boolean isitemviewswipeenabled() {}
/**
 * 当用户拖拽或者滑动item的时候需要我们告诉系统滑动或者拖拽的方向
 */
@override
public int getmovementflags(recyclerview recyclerview, recyclerview.viewholder viewholder) {}
/**
 * 当item被拖拽的时候被回调
 */
@override
public boolean onmove(recyclerview r, viewholder rholer, viewholder tholder) {}

/**
 * 当view被滑动删除的时候
 */
@override
public void onswiped(recyclerview.viewholder viewholder, int direction) {}



        isitemviewswipeenabled()返回值是否可以拖拽排序,true可以,false不可以,isitemviewswipeenabled()是否可以滑动删除,true可以,false不可以;这两个方法都是配置是否可以操作的。我们上面的代码中返回了一个成员变量值,并且这个值通过外部可以修改,所以提供了外部控制的方法。

        onmove()当item被拖拽排序移动到另一个item的位置的时候被回调,onswiped()当item被滑动删除到不见;这两个方法是当用户操作了,来回调我们,我们就该去更新ui了。这里我们提供了一个listener去通知外部,并且返回出去了必要的值,来降低代码耦合度。

        getmovementflags()说明一:是当用户拖拽或者滑动item的时候需要我们告诉系统滑动或者拖拽的方向,那我们又知道支持拖拽和滑动删除的无非就是linearlayoutmanager和gridlayoutmanager了,相当于我们老早的时候用的listview和gridview了。所以我们根据布局管理器的不同做了响应的区分。

        getmovementflags()说明二:其他都好理解,就是这里的return makemovementflags(dragflag, swipeflag);这句话是最终的返回值,也就是它决定了我们的拖拽或者滑动的方法。第一个参数是拖拽flag,第二个是滑动的flag。

        重新定义defaultitemtouchhelper

        我们记得上面定义了一个defaultitemtouchhelper,它的构造中需要传一个itemtouchhelper.callback,既然我们实现礼了,我们再把defaultitemtouchhelper做个封装,使使用者更傻瓜式的调用。

[Java] 查看源文件 复制代码
public class defaultitemtouchhelper extends yolandaitemtouchhelper {

  private defaultitemtouchhelpcallback itemtouchhelpcallback;

  public defaultitemtouchhelper(defaultitemtouchhelpcallback.onitemtouchcallbacklistener onitemtouchcallbacklistener) {
    super(new defaultitemtouchhelpcallback(onitemtouchcallbacklistener));
    itemtouchhelpcallback = (defaultitemtouchhelpcallback) getcallback();
  }

  /**
   * 设置是否可以被拖拽
   *
   * @param candrag 是true,否false
   */
  public void setdragenable(boolean candrag) {
    itemtouchhelpcallback.setdragenable(candrag);
  }

  /**
   * 设置是否可以被滑动
   *
   * @param canswipe 是true,否false
   */
  public void setswipeenable(boolean canswipe) {
    itemtouchhelpcallback.setswipeenable(canswipe);
  }
}

        现在我们看到已经不需要传itemtouchhelper.callback给itemtouchhelper了,只需要传我们在defaultitemtouchhelpcallback中定义好的onitemtouchcallbacklistener就好了,而且提供了设置是否可以滑动和是否可以拖拽的方法,而onitemtouchcallbacklistener只是通知外部滑动了、删除了,你去更新ui吧。

        这里可以有的同学会有疑问,上面原来不是继承itemtouchhelper吗?这里咋就变成了yolandaitemtouchhelper了呢?因为我们看到这里多了一句itemtouchhelpcallback = getcallback();,这个getcallback();这个方法是没有的,是我们在yolandaitemtouchhelper中自定义的,因为我们想在defaultitemtouchhelper中提供外部设置是否可以拖拽和滑动删除的方法,就得拿到这个callback,所以我看了下源码,我们在itemtouchhelper构造中把callback穿进去,它保存的时候一个package级别的成员变量,所以我在android.support.v7.widget.helper包下新建了一个yolandaitemtouchhelper类:

[Java] 查看源文件 复制代码
public class yolandaitemtouchhelper extends itemtouchhelper {
  public yolandaitemtouchhelper(callback callback) {
    super(callback);
  }

  public callback getcallback() {
    return mcallback;
  }
}

        如何投入使用

        好扯淡也扯完了,封装也封装完了,那么接下来就来在activity中使用下咯:

        recyclerview绑定itemtouchhelper

        没啥好说的用itemtouchhelper.attachtorecyclerview(recyclerview)绑定recyclerview和itemtouchhelper,并且只是允许拖拽和滑动删除item:

[Java] 查看源文件 复制代码
defaultitemtouchhelper itemtouchhelper = new defaultitemtouchhelper(onitemtouchcallbacklistener);
itemtouchhelper.attachtorecyclerview(recyclerview);
itemtouchhelper.setdragenable(true);
itemtouchhelper.setswipeenable(true);

        看到上面还缺少一个onitemtouchcallbacklistener吧,这个也比较重要。

        使用callback自定义的onitemtouchcallbacklistener刷新ui

        我们在自定义callback的时候不是在onmove()和onswiped()方法中回调onitemtouchcallbacklistener去更新ui吗?这里就是onitemtouchcallbacklistener如何更新ui的操作了,完成这个操作,那么我们的目的就达到了:

[Java] 查看源文件 复制代码
private defaultitemtouchhelpcallback.onitemtouchcallbacklistener onitemtouchcallbacklistener = new defaultitemtouchhelpcallback.onitemtouchcallbacklistener() {
  @override
  public void onswiped(int adapterposition) {
    // 滑动删除的时候,从数据源移除,并刷新这个item。
    if (userinfolist != null) {
      userinfolist.remove(adapterposition);
      mainadapter.notifyitemremoved(adapterposition);
    }
  }

  @override
  public boolean onmove(int srcposition, int targetposition) {
    if (userinfolist != null) {
      // 更换数据源中的数据item的位置
      collections.swap(userinfolist, srcposition, targetposition);
      // 更新ui中的item的位置,主要是给用户看到交互效果
      mainadapter.notifyitemmoved(srcposition, targetposition);
      return true;
    }
    return false;
  }
};

        到这里就结束了,不信你去试试,源码传送门。


分享到:  QQ好友和群 QQ空间 微信
收藏收藏 支持支持 反对反对

14

主题

8742

帖子

-2372

安币

限制会员

沙发
发表于 2017-12-5 17:57:57 | 只看该作者
感谢大神~

3

主题

8787

帖子

-2501

安币

限制会员

QQ达人

板凳
发表于 2017-12-6 13:35:18 | 只看该作者
感谢大神~

0

主题

8771

帖子

-2558

安币

限制会员

地板
发表于 2017-12-7 02:06:19 | 只看该作者
楼主是好人,回个帖会有安币吗?

0

主题

8736

帖子

-2515

安币

限制会员

5#
发表于 2017-12-7 14:45:05 | 只看该作者
安卓巴士是个不错的网站,我来顶个贴~

92

主题

8905

帖子

2069

安币

Android大神

Rank: 6Rank: 6

6#
发表于 2017-12-8 08:24:12 | 只看该作者
支持,感谢,祝巴士越来越好~

0

主题

8628

帖子

-2416

安币

限制会员

7#
发表于 2017-12-9 02:17:18 | 只看该作者
感谢分享,楼主V5~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| 申请友链|手机版|站点统计|重庆时时彩独胆倍投 ( 粤ICP备15117877号 )

快速回复 返回顶部 返回列表
小说 小说 小说 小说 小说 小说
小说 小说 小说 小说 小说 小说
小说 小说 小说 小说 小说 小说