Android LRecyclerView实现Item侧滑菜单、长按拖拽Item、滑动删除Item等功能

来源:互联网 发布:淘宝店铺链接在哪里 编辑:程序博客网 时间:2024/05/17 04:39

目录(?)[+]

LRecyclerView能做什么?

如果你之前没有听说过LRecyclerView,那么请参考: 
Android LRecyclerView实现下拉刷新,滑动到底部自动加载更多

经过再三思考,同时也为了大家使用方便,LRecyclerView集成了SwipeMenu系列功能,包括Item侧滑菜单、长按拖拽Item,滑动删除Item等功能。

demo apk下载地址:点我下载

功能演示

本次新增SwipeMenu系列功能描述如下:

  1. 左右两侧都有菜单;
  2. 根据ViewType显示菜单;
  3. 长按拖拽Item(List),与菜单结合;
  4. 长按拖拽Item(Grid);
  5. 滑动删除Item;
  6. 指定某个Item不能拖拽或者不能滑动删除;
  7. 用SwipeMenuLayout实现你自己的侧滑。

项目地址:https://github.com/jdsjlzx/LRecyclerView

SwipeMenuAdapter

为了实现SwipeMenu的功能,此次新增了一个SwipeMenuAdapter类。

SwipeMenuAdapter与library中已经存在的LRecyclerViewAdapter会不会冲突呢?答案是不会。SwipeMenuAdapter是用户级别的基类adapter,也就是用户需要继承SwipeMenuAdapter去实现自己的adapter,还像之前那样使用即可。

SwipeMenuAdapter类的定义:

<code class="hljs php has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">abstract</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">SwipeMenuAdapter</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">VH</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">RecyclerView</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ViewHolder</span>> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">RecyclerView</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Adapter</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">VH</span>> </span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

实现自己的MenuAdapter:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> MenuAdapter extends SwipeMenuAdapter<MenuAdapter.DefaultViewHolder> {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> List<ItemModel> mDataList = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<>();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">MenuAdapter</span>() {    }    @Override    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getItemCount</span>() {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> mDataList.size();    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> List<ItemModel> <span class="hljs-title" style="box-sizing: border-box;">getDataList</span>() {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> mDataList;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setDataList</span>(Collection<ItemModel> list) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mDataList.clear();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mDataList.addAll(list);        notifyDataSetChanged();    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">addAll</span>(Collection<ItemModel> list) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> lastIndex = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mDataList.size();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mDataList.addAll(list)) {            notifyItemRangeInserted(lastIndex, list.size());        }    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">remove</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {        mDataList.remove(position);        notifyItemRemoved(position);        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(position != mDataList.size()){ <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 如果移除的是最后一个,忽略</span>            notifyItemRangeChanged(position, mDataList.size() - position);        }    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">clear</span>() {        mDataList.clear();        notifyDataSetChanged();    }    @Override    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> View <span class="hljs-title" style="box-sizing: border-box;">onCreateContentView</span>(ViewGroup parent, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> viewType) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> LayoutInflater.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span>(parent.getContext()).inflate(R.layout.list_item_text_swipe, parent, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);    }    @Override    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> MenuAdapter.DefaultViewHolder <span class="hljs-title" style="box-sizing: border-box;">onCompatCreateViewHolder</span>(View realContentView, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> viewType) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DefaultViewHolder(realContentView);    }    @Override    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onBindViewHolder</span>(MenuAdapter.DefaultViewHolder holder, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {        String item = mDataList.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>(position).title;        DefaultViewHolder viewHolder = holder;        viewHolder.tvTitle.setText(item);    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> class DefaultViewHolder extends RecyclerView.ViewHolder {        TextView tvTitle;        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">DefaultViewHolder</span>(View itemView) {            super(itemView);            tvTitle = (TextView) itemView.findViewById(R.id.tv_title);        }    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li></ul>

是不是很方便?MenuAdapter基本的功能都满足了,直接拷贝到项目中即可使用。

上面说了那么多,关键的也就这几句:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">mDataAdapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> MenuAdapter();mDataAdapter.setDataList(dataList);mLRecyclerViewAdapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LRecyclerViewAdapter(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, mDataAdapter);mRecyclerView.setAdapter(mLRecyclerViewAdapter);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

下面具体分析每个功能。

左右两侧都有菜单

效果图:

具体使用步骤如下。

  • 为SwipeRecyclerView的Item创建菜单
<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置菜单创建器。</span>mRecyclerView.setSwipeMenuCreator(swipeMenuCreator);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置菜单Item点击监听事件        mRecyclerView.setSwipeMenuItemClickListener(menuItemClickListener);</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

其中swipeMenuCreator和menuItemClickListener代码如下:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 菜单创建器。在Item要创建菜单的时候调用。 */</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> SwipeMenuCreator swipeMenuCreator = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SwipeMenuCreator() {        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreateMenu</span>(SwipeMenu swipeLeftMenu, SwipeMenu swipeRightMenu, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> viewType) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> size = getResources().getDimensionPixelSize(R.dimen.item_height);            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加左侧的,如果不添加,则左侧不会出现菜单。</span>            {                SwipeMenuItem addItem = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SwipeMenuItem(mContext)                        .setBackgroundDrawable(R.drawable.selector_green)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 点击的背景。</span>                        .setImage(R.mipmap.ic_action_add) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 图标。</span>                        .setWidth(size) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 宽度。</span>                        .setHeight(size); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 高度。</span>                swipeLeftMenu.addMenuItem(addItem); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加一个按钮到左侧菜单。</span>                SwipeMenuItem closeItem = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SwipeMenuItem(mContext)                        .setBackgroundDrawable(R.drawable.selector_red)                        .setImage(R.mipmap.ic_action_close)                        .setWidth(size)                        .setHeight(size);                swipeLeftMenu.addMenuItem(closeItem); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加一个按钮到左侧菜单。</span>            }            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加右侧的,如果不添加,则右侧不会出现菜单。</span>            {                SwipeMenuItem deleteItem = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SwipeMenuItem(mContext)                        .setBackgroundDrawable(R.drawable.selector_red)                        .setImage(R.mipmap.ic_action_delete)                        .setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"删除"</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 文字,还可以设置文字颜色,大小等。。</span>                        .setTextColor(Color.WHITE)                        .setWidth(size)                        .setHeight(size);                swipeRightMenu.addMenuItem(deleteItem);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加一个按钮到右侧侧菜单。</span>                SwipeMenuItem closeItem = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SwipeMenuItem(mContext)                        .setBackgroundDrawable(R.drawable.selector_purple)                        .setImage(R.mipmap.ic_action_close)                        .setWidth(size)                        .setHeight(size);                swipeRightMenu.addMenuItem(closeItem); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加一个按钮到右侧菜单。</span>                SwipeMenuItem addItem = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SwipeMenuItem(mContext)                        .setBackgroundDrawable(R.drawable.selector_green)                        .setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"添加"</span>)                        .setTextColor(Color.WHITE)                        .setWidth(size)                        .setHeight(size);                swipeRightMenu.addMenuItem(addItem); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加一个按钮到右侧菜单。</span>            }        }    };    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**     * 菜单点击监听。     */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> OnSwipeMenuItemClickListener menuItemClickListener = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnSwipeMenuItemClickListener() {        <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**         * Item的菜单被点击的时候调用。         *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> closeable       closeable. 用来关闭菜单。         *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> adapterPosition adapterPosition. 这个菜单所在的item在Adapter中position。         *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> menuPosition    menuPosition. 这个菜单的position。比如你为某个Item创建了2个MenuItem,那么这个position可能是是 0、1,         *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> direction       如果是左侧菜单,值是:SwipeMenuRecyclerView#LEFT_DIRECTION,如果是右侧菜单,值是:SwipeMenuRecyclerView#RIGHT_DIRECTION.         */</span>        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onItemClick</span>(Closeable closeable, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> adapterPosition, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> menuPosition, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> direction) {            closeable.smoothCloseMenu();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 关闭被点击的菜单。</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (direction == LRecyclerView.RIGHT_DIRECTION) {                Toast.makeText(mContext, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"list第"</span> + adapterPosition + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"; 右侧菜单第"</span> + menuPosition, Toast.LENGTH_SHORT).show();            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (direction == LRecyclerView.LEFT_DIRECTION) {                Toast.makeText(mContext, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"list第"</span> + adapterPosition + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"; 左侧菜单第"</span> + menuPosition, Toast.LENGTH_SHORT).show();            }        }    };</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li></ul>

从上面代码可以看出,swipeMenuCreator完成了左右菜单的创建,menuItemClickListener实现了菜单的点击事件。

需要注意的是,LRecyclerView提供了下面两个方法,具体使用请详见demo。

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">openLeftMenu</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> duration) {        openMenu(position, LEFT_DIRECTION, duration);    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">openRightMenu</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {        openMenu(position, RIGHT_DIRECTION, SwipeMenuLayout.DEFAULT_SCROLLER_DURATION);    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

openLeftMenu:打开item的左边菜单 
openRightMenu:打开item的右边菜单

这里关键的就是这个position(详细请参考demo),先埋下个伏笔,后面介绍。

根据ViewType显示菜单

效果图:

根据ViewType决定SwipeMenu在哪一行出现,可以左侧,可以右侧。

自定义MenuViewTypeAdapter,代码如下:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MenuViewTypeAdapter</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MenuAdapter</span> {</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> VIEW_TYPE_MENU = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> VIEW_TYPE_NONE = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getItemViewType</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> position % <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ? VIEW_TYPE_MENU : VIEW_TYPE_NONE;    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

在实现swipeMenuCreator 时,需要根据ItemViewType值来决定是否创建左右菜单。

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> SwipeMenuCreator swipeMenuCreator = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SwipeMenuCreator() {        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreateMenu</span>(SwipeMenu swipeLeftMenu, SwipeMenu swipeRightMenu, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> viewType) {        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 根据Adapter的ViewType来决定菜单的样式、颜色等属性、或者是否添加菜单。</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (viewType == MenuViewTypeAdapter.VIEW_TYPE_NONE) {                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Do nothing.</span>            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (viewType == MenuViewTypeAdapter.VIEW_TYPE_MENU) {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> size = getResources().getDimensionPixelSize(R.dimen.item_height);                ......            }        }    };</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

长按拖拽Item(List),与菜单结合

效果图:

关键代码:

<code class="hljs ruby has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">mRecyclerView.setLongPressDragEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 开启拖拽功能        mRecyclerView.setOnItemMoveListener(onItemMoveListener);<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 监听拖拽,更新<span class="hljs-constant" style="box-sizing: border-box;">UI</span>。</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

onItemMoveListener具体如下:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**     * 当Item移动的时候。     */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> OnItemMoveListener onItemMoveListener = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnItemMoveListener() {        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onItemMove</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> fromPosition, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> toPosition) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> adjFromPosition = mLRecyclerViewAdapter.getAdapterPosition(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>, fromPosition);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> adjToPosition = mLRecyclerViewAdapter.getAdapterPosition(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>, toPosition);            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 当Item被拖拽的时候。</span>            Collections.swap(mDataAdapter.getDataList(), adjFromPosition, adjToPosition);            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Be carefull in here!</span>            mLRecyclerViewAdapter.notifyItemMoved(fromPosition, toPosition);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回true表示处理了,返回false表示你没有处理。</span>        }        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onItemDismiss</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 当Item被滑动删除掉的时候,在这里是无效的,因为这里没有启用这个功能。</span>            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 使用Menu时就不用使用这个侧滑删除啦,两个是冲突的。</span>        }    };</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

注意下面代码:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> adjFromPosition = mLRecyclerViewAdapter.getAdapterPosition(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>, fromPosition);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> adjToPosition = mLRecyclerViewAdapter.getAdapterPosition(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>, toPosition);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

关于position的位置,为了大家使用方便,特在LRecyclerViewAdapter中提供了一个方法getAdapterPosition(boolean isCallback, int position)。

  • isCallback 含义:position是否接口回调中带来的
  • position 含义:如果不是接口回调,就是用户自己指定的position
  • getAdapterPosition(boolean isCallback, int position)只用于非LRecyclerViewAdapter提供的接口。

举例说明:

  • setOnItemMoveListener不是 LRecyclerViewAdapter自带接口(也就是内部方法),需要调用getAdapterPosition方法获得正确的position
  • 如setOnItemClickLitener 是 LRecyclerViewAdapter自带接口,接口里面自带了position,用户就不必调用getAdapterPosition方法,直接使用就可以了。
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">mLRecyclerViewAdapter.setOnItemClickLitener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnItemClickLitener() {            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onItemClick</span>(View view, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {                String text = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Click position = "</span> + position;            }            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onItemLongClick</span>(View view, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {            }        });</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

长按拖拽Item(Grid)

效果图:

与list功能一样,只是布局不一样。

滑动直接删除Item

效果图:

注意:

滑动删除和滑动菜单是互相冲突的,两者只能出现一个。

关键代码:

<code class="hljs ruby has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">mRecyclerView.setLongPressDragEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);mRecyclerView.setItemViewSwipeEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 开启滑动删除        mRecyclerView.setOnItemMoveListener(onItemMoveListener);<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 监听拖拽,更新<span class="hljs-constant" style="box-sizing: border-box;">UI</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

按照配置就可以实现滑动删除。

指定某个Item不能拖拽或者不能滑动删除

效果图:

关键代码:

<code class="hljs ruby has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">mRecyclerView.setLongPressDragEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);mRecyclerView.setItemViewSwipeEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 开启滑动删除。        mRecyclerView.setOnItemMoveListener(onItemMoveListener);<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 监听拖拽,更新<span class="hljs-constant" style="box-sizing: border-box;">UI</span>。        mRecyclerView.setOnItemMovementListener(onItemMovementListener);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

其中,onItemMovementListener具体实现如下:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 当Item被移动之前。 */</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> OnItemMovementListener onItemMovementListener = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnItemMovementListener() {        <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**         * 当Item在移动之前,获取拖拽的方向。         *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> recyclerView     {@link RecyclerView}.         *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> targetViewHolder target ViewHolder.         *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @return</span>         */</span>        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">onDragFlags</span>(RecyclerView recyclerView, RecyclerView.ViewHolder targetViewHolder) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 我们让第一个不能拖拽</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (targetViewHolder.getAdapterPosition() == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.INVALID;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回无效的方向。</span>            }            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (layoutManager <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> LinearLayoutManager) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 如果是LinearLayoutManager。</span>                LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (linearLayoutManager.getOrientation() == LinearLayoutManager.HORIZONTAL) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 横向的List。</span>                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.LEFT | OnItemMovementListener.RIGHT; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 只能左右拖拽。</span>                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 竖向的List。</span>                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.UP | OnItemMovementListener.DOWN; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 只能上下拖拽。</span>                }            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (layoutManager <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> GridLayoutManager) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 如果是Grid。</span>                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.LEFT | OnItemMovementListener.RIGHT | OnItemMovementListener.UP | OnItemMovementListener.DOWN; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 可以上下左右拖拽。</span>            }            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.INVALID;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回无效的方向。</span>        }        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">onSwipeFlags</span>(RecyclerView recyclerView, RecyclerView.ViewHolder targetViewHolder) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 我们让第一个不能滑动删除。</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (targetViewHolder.getAdapterPosition() == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.INVALID;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 返回无效的方向。</span>            }            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (layoutManager <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> LinearLayoutManager) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 如果是LinearLayoutManager</span>                LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (linearLayoutManager.getOrientation() == LinearLayoutManager.HORIZONTAL) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 横向的List。</span>                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.UP | OnItemMovementListener.DOWN; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 只能上下滑动删除。</span>                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 竖向的List。</span>                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.LEFT | OnItemMovementListener.RIGHT; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 只能左右滑动删除。</span>                }            }            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OnItemMovementListener.INVALID;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 其它均返回无效的方向。</span>        }    };</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li></ul>

onItemMoveListener具体实现如下:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**     * 当Item移动的时候。     */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> OnItemMoveListener onItemMoveListener = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnItemMoveListener() {        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onItemMove</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> fromPosition, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> toPosition) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> adjFromPosition = mLRecyclerViewAdapter.getAdapterPosition(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>, fromPosition);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> adjToPosition = mLRecyclerViewAdapter.getAdapterPosition(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>, toPosition);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (adjToPosition == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 保证第一个不被挤走。</span>                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;            }            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 当Item被拖拽的时候。</span>            Collections.swap(mDataAdapter.getDataList(), adjFromPosition, adjToPosition);            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Be carefull in here!</span>            mLRecyclerViewAdapter.notifyItemMoved(fromPosition, toPosition);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;        }        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onItemDismiss</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> adjPosition = mLRecyclerViewAdapter.getAdapterPosition(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>, position);            mDataAdapter.remove(adjPosition);            AppToast.showShortText(DragSwipeFlagsActivity.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"现在的第"</span> + adjPosition + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"条被删除。"</span>);        }    };</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>

通过代码中的注释,就可以明白了,一切尽在代码中。

用SwipeMenuLayout实现你自己的侧滑

效果图:

这个与LRecyclerView关系不大,但是与SwipeMenu关系密切。为了实现滑动菜单的功能,定义了SwipeMenuLayout。

SwipeMenuLayout类的定义:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">SwipeMenuLayout</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FrameLayout</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">SwipeSwitch</span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

在开头提到的SwipeMenuAdapter的

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    @Override    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final VH onCreateViewHolder(ViewGroup <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">parent</span>, int viewType) {        View contentView <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> onCreateContentView(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">parent</span>, viewType);        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mSwipeMenuCreator <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) {            SwipeMenuLayout swipeMenuLayout <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> (SwipeMenuLayout) LayoutInflater<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>from(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">parent</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getContext())<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>inflate(R<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>layout<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>layout_recyclerview_swipe_item_default, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">parent</span>, <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>);<span class="hljs-attribute" style="box-sizing: border-box;">...</span><span class="hljs-attribute" style="box-sizing: border-box;">...</span>}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

layout_recyclerview_swipe_item_default.xml

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><?xml version=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"1.0"</span> encoding=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"utf-8"</span>?><<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.github</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.jdsjlzx</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.swipe</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.SwipeMenuLayout</span> xmlns:android=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res/android"</span>    xmlns:swipe=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res-auto"</span>    android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span>    android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span>    swipe:contentViewId=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@+id/swipe_content"</span>    swipe:leftViewId=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@+id/swipe_left"</span>    swipe:rightViewId=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@+id/swipe_right"</span>>    <<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.github</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.jdsjlzx</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.swipe</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.SwipeMenuView</span>        android:id=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@id/swipe_left"</span>        android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span>        android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> />    <FrameLayout        android:id=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@id/swipe_content"</span>        android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span>        android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> />    <<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.github</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.jdsjlzx</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.swipe</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.SwipeMenuView</span>        android:id=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@id/swipe_right"</span>        android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span>        android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> /></<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.github</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.jdsjlzx</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.swipe</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.SwipeMenuLayout</span>></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

看来这个布局,你是不是有种恍然大悟的感觉呢?左右滑动就是通过SwipeMenuView来实现的。

项目地址:https://github.com/jdsjlzx/LRecyclerView,欢迎Star!

Thanks

SwipeRecyclerView 作者:严振杰

别看他年龄小,也很牛啊!


如果你觉得这篇文章对你有用,那么赞一个或者留个言吧!

另外下载Demo有意外收获啊!

如果你对LRecyclerView有什么好的想法或者建议,期待你的留言!

1 0