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



//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注册:
<activityandroid: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;@Overrideprotected 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的根布局idadapter.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() {@Overridepublic 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("完成");}}@Overridepublic void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {Log.e("TAG1231", "onItemDragMoving");}@Overridepublic 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() {@Overridepublic void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {ToastUtil.getInstance().showToast("继续向左滑动即可删除第" + (pos + 1) + "个位置的item");}@Overridepublic void clearView(RecyclerView.ViewHolder viewHolder, int pos) {}@Overridepublic void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {ToastUtil.getInstance().showToast("删除了第" + (pos + 1) + "个位置的item哦");}@Overridepublic void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {}};@Overridepublic void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {adapter.remove(position);}@Overridepublic 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*/@Overridepublic 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 = 0;} 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);}@Overrideprotected 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"><TextViewandroid: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.RecyclerViewandroid: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"><TextViewandroid: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" /><ImageViewandroid: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"><pathandroid: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---------------------------------------------------------------
相关文章:
117.Android 简单的拖拽列表+防止越界拖动(BaseRecyclerViewAdapterHelper)
//1.第一步 导入依赖库和权限: //依赖库: //RecyclerView implementation com.android.support:recyclerview-v7:28.0.0//RecyclerAdapter implementation com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28 //用到的权限: <!…...
什么是Struts2?有哪些优势
Java中Strutsl是最早的基于MVC模式的轻量级Web框架,它能够合理地划分代码结构,并包含验证框架、国际化框架等多种实用工具框架。但是随着技术的进步,Struts1的局限性也越来越多地暴露出来。为了符合更加灵活、高效的开发需求,Stru…...
Ubuntu22.04 安装Mongodb6.X
Ubuntu22.04 安装Mongodb6.X 1、Mongodb简介 1.1 什么是MongoDB? Mongodb是一个跨平台的面向文档的NoSQL数据库。它使用带有可选模式的类似JSON的BSON来存储数据。应用程序可以以JSON格式检索信息。 1.2 MongoDB的优点 可以快速开发web型应用,因为灵活,…...
启动内核,能启动内核但是无法进入内核,始终卡在某一地方,比如 No soundcards found.
项目场景: 配置好uboot后,启动内核,能启动内核但是无法进入内核,始终卡在某一地方,比如下图 ALSA device list:No soundcards found.问题描述 原因分析: 这是无法进入根文件系统而出现的错误,…...
SQL零基础入门学习(六)
SQL零基础入门学习(六) SQL零基础入门学习(五) SQL 通配符 通配符可用于替代字符串中的任何其他字符。 SQL 通配符用于搜索表中的数据。 在 SQL 中,可使用以下通配符: 演示数据库 在本教程中ÿ…...
股票、指数、快照、逐笔... 不同行情数据源的实时关联分析应用
在进行数据分析时经常需要对多个不同的数据源进行关联操作,因此在各类数据库的 SQL 语言中均包含了丰富的 join 语句,以支持批计算中的多种关联操作。 DolphinDB 不仅通过 join 语法支持了对于全量历史数据的关联处理,而且在要求低延时的实时…...
华为OD机试真题Python实现【 不含 101 的数】真题+解题思路+代码(20222023)
不含 101 的数 题目 小明在学习二进制时,发现了一类不含 101 的数, 也就是将数字用二进制表示,不能出现 101 。 现在给定一个正整数区间 [l,r],请问这个区间内包含了多少个不含 101 的数? 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Python)真题目录汇…...
centos7 搭建ELK(elasticsearch、logstash、kibana)
1、下载安装包 使用华为镜像站下载速度很快,华为镜像站:https://mirrors.huaweicloud.com/home,下载时需要保证版本一致 2、安装elasticsearch 解压到当前目录 [rootlocalhost elk]# tar zxvf elasticsearch-7.4.2-linux-x86_64.tar.gz 安…...
如何写新闻稿?写好新闻稿的技巧与步骤
新闻稿是传递新闻事件和信息的重要手段,是传媒工作中不可或缺的一部分。写好一篇新闻稿可以让受众了解更多信息,进一步提高他们的关注度。以下是一些写好新闻稿的技巧和步骤,帮助你有效地传达新闻。1、确定新闻的核心信息在开始写新闻稿之前&…...
抖音不想只做“开心果”
出品 | 何玺 排版 | 叶媛 2023一开年,抖音就新动作不断。先是宣布启动线上超市,继而又传出将在3月份试水外卖业务,展现出多面出击的姿态。 01 抖音杀入线上超市、外卖赛道 抖音正式杀入“线上超市”赛道。据多家媒体报道,抖音…...
MATLAB | 如何用MATLAB绘制这样有气泡感的网络图
今天给大家带来一款用来绘制有气泡感的网络图的工具函数,绘制效果如下: 花里胡哨的,气泡大小代表流入流出数据量综合,不同颜色的气泡代表属于不同类,两个气泡之间有连线代表有数据流动,连线透明度代表流动数…...
Linux 远程登录
Linux 一般作为服务器使用,而服务器一般放在机房,你不可能在机房操作你的 Linux 服务器。 这时我们就需要远程登录到Linux服务器来管理维护系统。 Linux 系统中是通过 ssh 服务实现的远程登录功能,默认 ssh 服务端口号为 22。 Window 系统…...
SAP中BOM基础数量及组件数量单位比例关系的注意事项
下图是BOM展开功能CS11在正式系统和测试系统的截图。从截图中的对比不难看出,最下级的原材料A20981-110在组件的数量为1,实际按BOM中的设定比例折算,应该是1个成品,对应需要0.125件原材料。但这里显示的并不是0.125PC,…...
华为OD机试真题Python实现【最大相连男生数】真题+解题思路+代码(20222023)
最大相连男生数 题目 学校组织活动,将学生排成一个矩形方阵。 请在矩形方阵中找到最大的位置相连的男生数量。 这个相连位置在一个直线上,方向可以是水平的、垂直的、成对角线的或者反对角线的。 注:学生个数不会超过 10000。 🔥🔥🔥🔥🔥👉👉👉👉👉�…...
Vue使用ElementUI对表单元素进行自定义校验
前言 在使用ElementUI的表单元素时候,除了做一些简单的非空处理校验,在一些特殊的场合,还需要我们做一些自定义校验。 其实ElementUI不仅提供了基本的非空校验,也对我们提供了自定义检验。 在使用的时候还是遇到了一些坑&#…...
linux的文件权限介绍
文件权限 在linux终端输入 ls -lh 出现下面界面 介绍 基本信息 其中的开头代表着文件类型和权限 而 root 和kali 则分别代表用户名和用户组名用户名顾名思义就是这个文件属于哪一个用户用户组是说自己在写好一个文件后,这个文件是属于该用户所有,…...
支付系统中的设计模式03:模板方法模式
在上一节末尾,留了一个需求问题,就是老板提出的「支付前锁定账户,支付后增加积分」这个需求「3」没有解决。有些文章写得比较好的人其实会有一些固定的结构格式,比如总分总、总分、分总、并列、对照、递进等等。这种固定的结构格式,就是文章的模板。把它挪到编程中,也是一…...
【黏住用户的不是小红书,而是它背后的那些人】
最近在研究CDC线下城市联盟的事情,周六与本地组织做了一场简单的活动,没想到现场开发者热情暴涨,现场沟通了很多,大家普遍有两层需求: 1.加入圈子沟通 2.互助学习提升 CDC,也就是线下圈子,如…...
基于STM32采用CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试(中篇)
3.2 SPI硬件时序方式 上面的3.1小节是采用SPI模拟时序驱动SD NAND,STM32本身集成有SPI硬件模块,可以直接利用STM32硬件SPI接口读写。 下面贴出底层的适配代码。 上面贴出的驱动代码里,已经将驱动接口部分和协议逻辑部分区分开了,替…...
0基础学插画是报班还是自学
学插画0基础是报班还是自学,众所周知,报班一定是提升插画水平的最有效途径,如果有经济能力,建议报班!那么报哪些插画课程班比较靠谱呢?同时给大家梳理了国内最新5大插画班排行榜,各有优势和特色…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
