android 仿IOS添加小组件的拖拽排序列表,使用SwipeRecyclerView

  • 前言
  • 干活
    • 找到合适的轮子
    • 添加依赖
    • 编写布局
    • 设置越界滚动
    • 初始化数据和点击事件
    • 创建侧滑菜单和点击菜单事件
    • 监听拖拽,更新UI
    • 监听触摸修改背景
  • Github
  • 完事

前言

听公司开发说,IOS的拖拽排序列表竟然是自带的控件。。。这也太省事了。。。
下图是IOS的添加小组件页面:

下图是我最终的仿造品:

下面是操作动图:

干活

找到合适的轮子

列表拖拽排序并不难做,用ItemTouchHelper和ItemTouchHelper.Callbck就比较好的解决,但是要加上侧滑显示菜单就要多点事情了,这时候找个合适的轮子能省事不少,也能少走一些坑。下面是我找到的一些参考内容:
@minwenping ---- RecyclerView的item拖动排序效果实现和它的ItemTouchHelper详解
@h6ah4i ---- android-advancedrecyclerview
@yanzhenjie ---- SwipeRecyclerView
有兴趣的朋友可以都看一下

我最后使用的是 @yanzhenjie ---- SwipeRecyclerView

因为它支持两种库

添加依赖

这里是我用到的第三方库

    // 顶部标题栏    implementation 'com.github.D10NGYANG:DL10TittleBar:1.0.2'    // 列表控件    implementation 'com.yanzhenjie.recyclerview:support:1.3.2'    // 刷新控件    implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-14'    // RecyclerAdapter框架    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.46'    // 控件注解    implementation 'com.jakewharton:butterknife:8.8.1'    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

在工程的build.gradle中添加:

allprojects {         repositories {             google()        jcenter()        maven {      url 'https://jitpack.io' }            }}

编写布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@android:color/white"    android:orientation="vertical">    <com.dlong.rep.dltittlebar.DLTittleBar        android:id="@+id/tittle_bar"        android:layout_width="match_parent"        android:layout_height="50dp"        app:barBackground="@android:color/white"        app:leftBtnColor="#3478f3"        app:leftBtnTxt="取消"        app:leftBtnVisible="true"        app:right1BtnVisible="false"        app:right2BtnColor="#3478f3"        app:right2BtnTxt="完成"        app:right2BtnVisible="true"        app:tittleTxt="">    </com.dlong.rep.dltittlebar.DLTittleBar>    <com.scwang.smartrefresh.layout.SmartRefreshLayout        android:id="@+id/sr_refresh"        android:layout_width="match_parent"        android:layout_height="match_parent">        <android.support.v4.widget.NestedScrollView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:fillViewport="true">            <LinearLayout                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:orientation="vertical" >                <TextView                    android:layout_width="match_parent"                    android:layout_height="wrap_content"                    android:layout_marginTop="50dp"                    android:gravity="center"                    android:text="添加小组件"                    android:textColor="@android:color/black"                    android:textSize="30sp"                    android:textStyle="bold" />                <TextView                    android:layout_width="match_parent"                    android:layout_height="wrap_content"                    android:layout_marginBottom="50dp"                    android:gravity="center"                    android:lineSpacingExtra="4sp"                    android:paddingLeft="30dp"                    android:paddingRight="30dp"                    android:text="快速浏览,及时从喜爱的应用中了解信息。在下方添加并整理您的小组件。"                    android:textColor="@android:color/black" />                <ImageView                    android:layout_width="match_parent"                    android:layout_height="1px"                    android:src="#c8c7cc" />                <com.yanzhenjie.recyclerview.SwipeRecyclerView                    android:id="@+id/rcv_select"                    android:layout_width="match_parent"                    android:layout_height="wrap_content" />                <ImageView                    android:layout_width="match_parent"                    android:layout_height="1px"                    android:src="#c8c7cc" />                <TextView                    android:layout_width="match_parent"                    android:layout_height="50dp"                    android:gravity="bottom"                    android:paddingLeft="20dp"                    android:paddingBottom="5dp"                    android:text="更多小组件"                    android:textColor="@android:color/tertiary_text_light"                    android:textSize="14sp" />                <ImageView                    android:layout_width="match_parent"                    android:layout_height="1px"                    android:src="#c8c7cc" />                <com.yanzhenjie.recyclerview.SwipeRecyclerView                    android:id="@+id/rcv_add"                    android:layout_width="match_parent"                    android:layout_height="wrap_content" />                <ImageView                    android:layout_width="match_parent"                    android:layout_height="1px"                    android:src="#c8c7cc" />                <RelativeLayout                    android:layout_width="match_parent"                    android:layout_height="50dp">                </RelativeLayout>            </LinearLayout>        </android.support.v4.widget.NestedScrollView>    </com.scwang.smartrefresh.layout.SmartRefreshLayout></LinearLayout>

设置越界滚动

        // 初始化越界滚动        srRefresh.setEnableRefresh(false);//是否启用下拉刷新功能        srRefresh.setEnableLoadMore(false);//是否启用上拉加载功能        srRefresh.setEnablePureScrollMode(true);//是否启用纯滚动模式        srRefresh.setEnableOverScrollBounce(true);//是否启用越界回弹        srRefresh.setEnableOverScrollDrag(true);//是否启用越界拖动(仿苹果效果)1.0.4        srRefresh.setEnableNestedScroll(true);//是否启用嵌套滚动

初始化数据和点击事件

        // 初始化数据        selectList.clear();        for (int i = 0; i < 5; i++) {                 DataBin bin = new DataBin();            bin.name = "计算器-" + i;            selectList.add(bin);        }        selectAdapter = new SelectAdapter(selectList);        selectAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {                 @Override            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {                     switch (view.getId()) {                         case R.id.img_delete:                        rcvSelect.smoothOpenRightMenu(position);                        break;                }            }        });        addList.clear();        for (int i = 5; i < 20; i++) {                 DataBin bin = new DataBin();            bin.name = "计算器-" + i;            addList.add(bin);        }        addAdapter = new AddAdapter(addList);        addAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {                 @Override            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {                     switch (view.getId()) {                         case R.id.img_add:                        DataBin bin = addList.get(position);                        selectList.add(bin);                        selectAdapter.notifyDataSetChanged();                        addList.remove(bin);                        adapter.notifyItemRemoved(position);                        break;                }            }        });

创建侧滑菜单和点击菜单事件

    /**     * 菜单创建器。     */    private SwipeMenuCreator mSwipeMenuCreator = new SwipeMenuCreator() {             @Override        public void onCreateMenu(SwipeMenu swipeLeftMenu, SwipeMenu swipeRightMenu, int position) {                 int width = getResources().getDimensionPixelSize(R.dimen.dp_60);            // 1. MATCH_PARENT 自适应高度,保持和Item一样高;            // 2. 指定具体的高,比如80;            // 3. WRAP_CONTENT,自身高度,不推荐;            int height = ViewGroup.LayoutParams.MATCH_PARENT;            // 添加右侧的,如果不添加,则右侧不会出现菜单。            {                     SwipeMenuItem deleteItem = new SwipeMenuItem(MainActivity.this).setBackground(                        R.drawable.selector_red)                        .setText("移除")                        .setTextColor(Color.WHITE)                        .setWidth(width)                        .setHeight(height);                swipeRightMenu.addMenuItem(deleteItem);// 添加一个按钮到右侧侧菜单。            }        }    };    /**     * RecyclerView的Item的Menu点击监听。     */    private OnItemMenuClickListener mItemMenuClickListener = new OnItemMenuClickListener() {             @Override        public void onItemClick(SwipeMenuBridge menuBridge, int position) {                 menuBridge.closeMenu();            int direction = menuBridge.getDirection(); // 左侧还是右侧菜单。            int menuPosition = menuBridge.getPosition(); // 菜单在RecyclerView的Item中的Position。            if (direction == SwipeRecyclerView.RIGHT_DIRECTION) {                     // 移除                DataBin bin = selectList.get(position);                addList.add(bin);                addAdapter.notifyDataSetChanged();                selectList.remove(bin);                selectAdapter.notifyItemRemoved(position);            }        }    };

监听拖拽,更新UI

    /**     * 拖拽监听     */    OnItemMoveListener mItemMoveListener = new OnItemMoveListener() {             @Override        public boolean onItemMove(RecyclerView.ViewHolder srcHolder, RecyclerView.ViewHolder targetHolder) {                 // 不同的ViewType不能拖拽换位置。            if (srcHolder.getItemViewType() != targetHolder.getItemViewType()) return false;            // 真实的Position:通过ViewHolder拿到的position都需要减掉HeadView的数量。            int fromPosition = srcHolder.getAdapterPosition() - rcvSelect.getHeaderCount();            int toPosition = targetHolder.getAdapterPosition() - rcvSelect.getHeaderCount();            Collections.swap(selectList, fromPosition, toPosition);            selectAdapter.notifyItemMoved(fromPosition, toPosition);            return true;// 返回true表示处理了并可以换位置,返回false表示你没有处理并不能换位置。        }        @Override        public void onItemDismiss(RecyclerView.ViewHolder srcHolder) {                 // 此方法在Item在侧滑删除时被调用。        }    };

监听触摸修改背景

    /**     * 触摸动作监听     */    private OnItemStateChangedListener mStateChangedListener = new OnItemStateChangedListener() {             @Override        public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {                 LinearLayout ll = viewHolder.itemView.findViewById(R.id.ll_item);            ImageView line = viewHolder.itemView.findViewById(R.id.line_bottom);            if (actionState == OnItemStateChangedListener.ACTION_STATE_DRAG) {                     // 状态:正在拖拽。                srRefresh.setEnableOverScrollBounce(false);//是否启用越界回弹                srRefresh.setEnableOverScrollDrag(false);//是否启用越界拖动(仿苹果效果)1.0.4                rcvSelect.setNestedScrollingEnabled(false);                // 拖拽的时候背景就透明了,这里我们可以添加一个特殊背景。                ll.setSelected(true);                line.setVisibility(View.INVISIBLE);            } else if (actionState == OnItemStateChangedListener.ACTION_STATE_SWIPE) {                     // 状态:滑动删除。            } else if (actionState == OnItemStateChangedListener.ACTION_STATE_IDLE) {                     // 状态:手指松开。                srRefresh.setEnableOverScrollBounce(true);//是否启用越界回弹                srRefresh.setEnableOverScrollDrag(true);//是否启用越界拖动(仿苹果效果)1.0.4                rcvSelect.setNestedScrollingEnabled(true);                // 在手松开的时候还原背景。                ll.setSelected(false);                line.setVisibility(View.VISIBLE);            }        }    };

Github

D10NGYANG/DragRecycleViewTest

完事

更多相关文章

  1. Android设置里面默认存储器选项(default write disk)的实现
  2. Android图像处理技术(实现Android中的PS)(三)
  3. Android(安卓)7.1添加一个 系统底层服务
  4. android注册 登录+修改帐号密码+添加资料+给指定帐号充值
  5. Android添加图片水印
  6. android没有告诉你的usr模式和eng模式的区别
  7. [Android(安卓)Pro] 控制硬加速 hardwareAccelerated 在3.0才有
  8. Android实用视图动画及工具系列之八:带头部的Viewpaper,结合头部的
  9. 【Android(安卓)Training - 15】云同步的实现 [Lesson 2 - 使用G

随机推荐

  1. java微信小程序解密AES/CBC/PKCS7Padding
  2. 包含带标记的值的XML属性文件
  3. JAVA实现排序-冒泡排序-优化冒泡排序
  4. 不幸的是,在声明按钮时,模拟器中出现了错误
  5. spark seq.max 报错 Caused by: java.lan
  6. 排序算法之 Java简单快速排序算法
  7. Java正则表达式提取字符
  8. Map集合的使用
  9. Java错误:线程“main”中的异常java.lang.
  10. 使用android nfc api写NFC tag信息