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

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

[复制链接]

196

主题

196

帖子

443

安币

手工艺人

跳转到指定楼层
楼主
本文来源:http://www.oneupabq.com/a/www.lwnews.net/

重庆时时彩独胆倍投 www.oneupabq.com,二是在全市形成了积极崇德向善,榜样层出不穷的良好社会风尚。这显然不是广大萌妹子想要的。


        效果演示

        

        需求和技术分析



  

    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号 )

快速回复 返回顶部 返回列表
小说 小说 小说 小说 小说 小说
小说 小说 小说 小说 小说 小说
小说 小说 小说 小说 小说 小说
东京快乐8 999彩票手机下载 黑龙江十一选五查询 体彩22选5走势图 河北十一选五开奖结果一定牛
一肖中特平公式网站 白小姐论坛 排列三吧 街机麻将 二分彩害了我