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

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

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

前言

听公司开发说,IOS的拖拽排序列表竟然是自带的控件。。。这也太省事了。。。
下图是IOS的添加小组件页面:
android 仿IOS添加小组件的拖拽排序列表,使用SwipeRecyclerView_第1张图片
下图是我最终的仿造品:
android 仿IOS添加小组件的拖拽排序列表,使用SwipeRecyclerView_第2张图片
下面是操作动图:

干活

找到合适的轮子

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

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

因为它支持两种库
android 仿IOS添加小组件的拖拽排序列表,使用SwipeRecyclerView_第3张图片

添加依赖

这里是我用到的第三方库

    // 顶部标题栏
    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

完事

你可能感兴趣的:(第三方依赖库,Android,recycleview,拖拽排序,侧滑菜单)