117.Android 简单的拖拽列表+防止越界拖动(BaseRecyclerViewAdapterHelper)

news2024/11/27 22:31:37

//1.第一步 导入依赖库和权限:

//依赖库:

//RecyclerView
implementation 'com.android.support:recyclerview-v7:28.0.0'

//RecyclerAdapter
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28'

//用到的权限:

<!--振动-->
<uses-permission android:name="android.permission.VIBRATE" />

 //2.第二步 新建ItemDraggableActivity页面:

//manifest注册:

<activity
    android:name=".phone.activity.ItemDraggableActivity"
    android:launchMode="singleTop"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateHidden"
    tools:ignore="LockedOrientationActivity" />

//activity代码:

/**
 * @author CJF
 */
public class ItemDraggableActivity extends AppCompatActivity implements BaseQuickAdapter.OnItemChildClickListener, View.OnClickListener {
    private final GridLayoutManager manager = new GridLayoutManager(this, 3);
    private final ItemDraggableAdapter adapter = new ItemDraggableAdapter(R.layout.item_draggable_item, new ArrayList<>());

    /**
     * 震动时长(毫秒)
     */
    private final int milliseconds = 50;
    private Vibrator vibrator;
    private RecyclerView mTreeListRecy;
    private TextView mEdit;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tree_list);

        //点击音效
        vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        mTreeListRecy = findViewById(R.id.mTreeListRecy);
        mEdit = findViewById(R.id.mEdit);
        mEdit.setOnClickListener(this);

        mTreeListRecy.setLayoutManager(manager);
        mTreeListRecy.setAdapter(adapter);

        DragAndSwipeCallback itemDragAndSwipeCallback = new DragAndSwipeCallback(adapter);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback);
        itemTouchHelper.attachToRecyclerView(mTreeListRecy);
        //可以不用设置,可以拖拽的方向,默认上下左右
        itemDragAndSwipeCallback.setDragMoveFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);

//         开启拖拽 设置可拖拽item的根布局id
        adapter.enableDragItem(itemTouchHelper, R.id.mItemDraggableItemLin, true);
        adapter.setOnItemDragListener(onItemDragListener);


        // 开启滑动删除
//        adapter.enableSwipeItem();
//        adapter.setOnItemSwipeListener(onItemSwipeListener);

        adapter.setOnItemChildClickListener(this);

        List<ItemDraggableBean> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            ItemDraggableBean bean = new ItemDraggableBean();
            bean.setName("数据" + i);
            list.add(bean);
        }
        adapter.addData(list);
    }

    /**
     * 拖拽监听
     */
    private OnItemDragListener onItemDragListener = new OnItemDragListener() {
        @Override
        public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) {
            Log.e("TAG1231", "onItemDragStart" + "你在拖拽第" + (pos + 1) + "个位置的item哦!");
            //震动
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                vibrator.vibrate(VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE));
            } else {
                vibrator.vibrate(milliseconds);
            }

            //按住变大
            viewHolder.itemView.setScaleX(1.2f);
            viewHolder.itemView.setScaleY(1.2f);
            viewHolder.itemView.setAlpha(0.5f);

            //改变数据状态
            ItemDraggableBean draggableBean = adapter.getData().get(pos);
            if (!draggableBean.isShow()) {
                List<ItemDraggableBean> data = adapter.getData();
                for (ItemDraggableBean bean : data) {
                    bean.setShow(true);
                }

                //循环遍历出所有的item布局 并显示图片
                //注意不可以直接使用 adapter.notifyDataSetChanged();数据刷新会导致直接调用onItemDragEnd()方法
                for (int i = 0; i < mTreeListRecy.getChildCount(); i++) {
                    View childAt = mTreeListRecy.getChildAt(i);
                    TextView textView = childAt.findViewById(R.id.mItemDraggableItemText);
                    View view = childAt.findViewById(R.id.mItemDraggableItemImg);
                    view.setVisibility(View.VISIBLE);
                    Log.e("TAG1231", "textView:" + textView.getText().toString());
                }

                mEdit.setText("完成");
            }

        }

        @Override
        public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {
            Log.e("TAG1231", "onItemDragMoving");
        }

        @Override
        public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {
            Log.e("TAG1231", "onItemDragEnd" + "拖拽到了第" + (pos + 1) + "个位置哦!");
            //变回原来大小
            viewHolder.itemView.setScaleX(1.0f);
            viewHolder.itemView.setScaleY(1.0f);
            viewHolder.itemView.setAlpha(1.0f);
        }
    };

    OnItemSwipeListener onItemSwipeListener = new OnItemSwipeListener() {
        @Override
        public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {
            ToastUtil.getInstance().showToast("继续向左滑动即可删除第" + (pos + 1) + "个位置的item");
        }

        @Override
        public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {

        }

        @Override
        public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {
            ToastUtil.getInstance().showToast("删除了第" + (pos + 1) + "个位置的item哦");
        }

        @Override
        public void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {

        }
    };

    @Override
    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
        adapter.remove(position);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.mEdit:
                boolean isEdit = "编辑".equals(mEdit.getText().toString());
                List<ItemDraggableBean> data = adapter.getData();
                for (ItemDraggableBean bean : data) {
                    bean.setShow(isEdit);
                }
                adapter.notifyDataSetChanged();
                mEdit.setText(isEdit ? "完成" : "编辑");
                break;
            default:
                break;
        }
    }

}

//3.第三步 新建DragAndSwipeCallback类继承ItemDragAndSwipeCallback,重写onChildDraw 防止越界拖动:

/**
 * @author CJF
 * 重写onChildDraw 防止越界拖动
 */
public class DragAndSwipeCallback extends ItemDragAndSwipeCallback {

    public DragAndSwipeCallback(BaseItemDraggableAdapter adapter) {
        super(adapter);
    }

    /**
     * 重写onChildDraw 防止越界拖动
     *
     * @param c
     * @param recyclerView
     * @param viewHolder
     * @param dX
     * @param dY
     * @param actionState
     * @param isCurrentlyActive
     */
    @Override
    public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        float topY = viewHolder.itemView.getTop() + dY;
        float bottomY = topY + viewHolder.itemView.getHeight();

        float leftX = viewHolder.itemView.getLeft() + dX;
        float rightX = leftX + viewHolder.itemView.getWidth();

        if (topY < 0) {
            dY = 0;
        } else if (bottomY > recyclerView.getHeight()) {
            dY = recyclerView.getHeight() - viewHolder.itemView.getHeight() - viewHolder.itemView.getTop();
        }

        if (leftX < 0) {
            dX = viewHolder.itemView.getWidth() - viewHolder.itemView.getRight();
        } else if (rightX > recyclerView.getWidth()) {
            dX = recyclerView.getWidth() - viewHolder.itemView.getWidth() - viewHolder.itemView.getLeft();
        }

        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

}

//4.第四步 新建ItemDraggableAdapter适配器类:

/**
 * @author CJF
 */
public class ItemDraggableAdapter extends BaseItemDraggableAdapter<ItemDraggableBean, BaseViewHolder> {

    public ItemDraggableAdapter(List<ItemDraggableBean> data) {
        super(data);
    }

    public ItemDraggableAdapter(int layoutResId, List<ItemDraggableBean> data) {
        super(layoutResId, data);

    }

    @Override
    protected void convert(BaseViewHolder helper, ItemDraggableBean item) {
        helper.setText(R.id.mItemDraggableItemText, item.getName());
        helper.setGone(R.id.mItemDraggableItemImg, item.isShow());
        helper.addOnClickListener(R.id.mItemDraggableItemImg);
    }

}

//5.第五步 新建ItemDraggableBean类:

/**
 * @author CJF
 */
public class ItemDraggableBean {
    private String name;
    private boolean isShow = false;

    public ItemDraggableBean() {
    }

    public ItemDraggableBean(String name, boolean isShow) {
        this.name = name;
        this.isShow = isShow;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isShow() {
        return isShow;
    }

    public void setShow(boolean show) {
        isShow = show;
    }

}

//6.第六步 各个xml布局文件以及svg图片文件:

//activity_tree_list:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/color_white"
    android:orientation="vertical">

    <TextView
        android:id="@+id/mEdit"
        android:background="@drawable/selector_common_item"
        android:textColor="@color/colorAccent"
        android:textStyle="bold"
        android:textSize="18sp"
        android:gravity="center"
        android:text="编辑"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/mTreeListRecy"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

//item_draggable_item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/bg_search"
    android:layout_margin="@dimen/dp_5"
    android:id="@+id/mItemDraggableItemLin"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/mItemDraggableItemText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="left|center_vertical"
        android:minHeight="@dimen/dp_50"
        android:padding="@dimen/dp_10"
        android:text="text"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_15" />

    <ImageView
        android:scaleType="center"
        android:id="@+id/mItemDraggableItemImg"
        android:src="@drawable/crm_close"
        android:layout_width="@dimen/dp_50"
        android:layout_height="match_parent"/>

</LinearLayout>

//svg图片文件  crm_close:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

//------------------------------------------------------END---------------------------------------------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/364428.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【华为OD机试模拟题】用 C++ 实现 - 求最大数字

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

优思学院:六西格玛管理的优势有哪些?

六西格玛的优势有哪些呢&#xff1f;以下我们来探讨一下。 一・降低企业整体成本 对企业而言&#xff0c;不良品要么被废弃&#xff0c;要么需要重新加工&#xff0c;或者需要在客户现场维修或更换&#xff0c;这些都会增加企业成本。根据美国的统计数据&#xff0c;执行3σ管…

搭建Scala集成开发环境

文章目录前言搭建Scala集成开发环境&#xff08;一&#xff09;启动IDEA&#xff08;二&#xff09;安装Scala插件&#xff08;四&#xff09;创建Scala项目1、创建Scala项目 - ScalaDemo012、创建Scala类 - HelloWorld3、创建Scala单例对象 - TestHelloWorld&#xff08;五&am…

HIVE 基础(四)

目录 分桶&#xff08;Bucket&#xff09; 设定属性 定义分桶 案例 建表语句 表数据 上传到数据 创建分桶语句 加载数据 分桶抽样&#xff08;Sampling&#xff09; 随机抽样---整行数据 随机抽样---指定列 随机抽样---百分比 随机抽样---抽取行数 Hive视图&#…

计算机基础知识——认识寄存器

下面我们就来介绍一下关于寄存器的相关内容。我们知道&#xff0c;寄存器是 CPU 内部的构造&#xff0c;它主要用于信息的存储。除此之外&#xff0c;CPU 内部还有运算器&#xff0c;负责处理数据&#xff1b;控制器控制其他组件&#xff1b;外部总线连接 CPU 和各种部件&#…

【软件测试】自动化测试的科幻大片,揭开面纱的后背......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 只要一听到 “自动化…

Solon v2.1.4 发布。支持 java、kotlin、groovy!

本次发布&#xff0c;重点测试和验证了在 java、kotlin、groovy 三种 jvm 语言里&#xff0c;开箱即用的特性。并发布 Solon Initializr&#xff1a; https://solon.noear.org/start/ &#xff08;也即将发布 idea 插件&#xff09; 最近&#xff0c;与小诺开源团队合作发布了…

JS中如何将一个普通对象转换为可迭代对象,并且可使用for...of迭代对象,内含手写一个简单的迭代器

文章目录一、认识迭代器二、为类数组添加迭代器方法三、为colorObj对象添加迭代器方法四、优化colorObj代码五、ES6内置迭代对象方法这里有一个普通对象&#xff1a; const colorObj {white: "小白",black: "小黑",gray: "小灰", }如何对 colo…

hyper-v安装koolshare软路由

注意 windows更改适配器配置&#xff0c;为hostonly适配器配置两个IP hyper-v虚拟机内存设置为2G&#xff08;windows pe启动需要&#xff09; hyper-v虚拟机配置网络》选择hostonly网络 以管理员身份运行IMG写盘工具 BIOS从IDE启动 去掉DVD驱动器 添加硬件》网络适配器》wan网…

华为机试题:HJ84 统计大写字母个数(python)

文章目录&#xff08;1&#xff09;题目描述&#xff08;2&#xff09;Python3实现&#xff08;3&#xff09;知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…

10 种主数据模型设计示例分享,推荐收藏

主数据模型是主数据管理的基础&#xff0c;一个完整的、可扩展的、相对稳定的主数据模型对于主数据管理的成功起着重要的作用。规划、创建主数据模型的过程&#xff0c;是梳理主数据管理体系的过程&#xff0c;目的是建立一个良好的资源目录结构&#xff0c;划分合理的资源粒度…

网关的通用设计框架

概念 网关&#xff0c;很多地方将网关比如成门&#xff0c; 没什么问题&#xff0c; 但是需要区分网关与网桥的区别。 网桥:工作在数据链路层&#xff0c;在不同或相同类型的LAN之间存储并转发数据帧&#xff0c;必要时进行链路层上的协议转换。可连接两个或多个网络&#xf…

从0到1一步一步玩转openEuler--22 管理服务-关闭、暂停、休眠系统服务

文章目录22 管理服务-关闭、暂停、休眠系统服务22.1 systemctl命令22.2 关闭系统22.3 重启系统22.4 使系统待机22.5 使系统休眠22 管理服务-关闭、暂停、休眠系统服务 22.1 systemctl命令 systemd通过systemctl命令可以对系统进行关机、重启、休眠等一系列操作。当前仍兼容部…

WSO2 apim 多租户来区分api

WSO2 apim 多租户来区分api1. Tenant1.1 Add new tenant1.2 Add Role/User1.3 Published Api2. Delete Teant3. AwakeningWSO2安装使用的全过程详解: https://blog.csdn.net/weixin_43916074/article/details/127987099. Official Document: Managing Tenants. 1. Tenant 1.1 …

电脑常用知识与工作常用工具

什么是电脑快捷键&#xff1f; 所谓快捷键就是使用键盘上某一个或某几个键的组合完成一条功能命令&#xff0c;从而达到提高操作速度的目的。 键盘布局 主键盘区&#xff0c;数字辅助键盘区、F键功能键盘区、控制键区&#xff0c;对于多功能键盘还增添了快捷键区 一、常用快捷…

多线程Thread常用方法和状态

Thread类 及常见方法 1、常见构造方法 方法说明Thread()创建线程对象Thread(Runnable target)使用 Runnable 对象创建线程对象Thread(String name)创建线程对象&#xff0c;并命名Thread(Runnable target, String name)使用 Runnable 对象创建线程对象&#xff0c;并命名Thre…

微信银行卡如何解除绑定?图文教程,快速解除

随着移动支付的普及&#xff0c;微信支付成为人们生活中不可或缺的支付方式。在微信支付中绑定银行卡可以让用户更方便地进行支付&#xff0c;但有时候需要解除银行卡的绑定。那么&#xff0c;微信银行卡如何解除绑定呢&#xff1f;在本文中&#xff0c;小编将详细介绍微信解除…

ZooKeeper实现分布式队列、分布式锁和选举详解

提示&#xff1a;本文章非原创&#xff0c;记录一下优秀的干货。 [原创参考]&#xff1a;https://blog.csdn.net/qq_40378034/article/details/117014648 前言 ZooKeeper源码的zookeeper-recipes目录下提供了分布式队列、分布式锁和选举的实现GitHub地址。 本文主要对这几种实…

XXL-JOB怎么玩?

官网&#xff1a;https://www.xuxueli.com/xxl-job/文档&#xff1a;https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E5%B9%B3%E5%8F%B0XXL-JOB%E3%80%8BXXL-JOB主要有调度中心、执行器、任务。开放源产品&#…

数据的存储(2)——浮点型

前言&#xff1a;内容是关于浮点型在内存中的存储详解及例子 数据的存储&#xff08;1&#xff09;——整型&#xff08;点击即跳转&#xff09; 浮点数的存储规则 任意一个二进制浮点数可以表示成以下形式&#xff1a; (-1)^S * M * 2^E (-1)^S表示符号位&#xff0c;当S0…