[Android]RecycleView的item用法

RecyclerView 是 Android 提供的一个强大的列表控件,用来显示大量数据。

RecyclerView 的主要特点

1. 高性能的视图复用机制

Recycle就是循环的意思,那么recycleview的特点也很鲜明了,它只会创建出在屏幕内和一定缓存的itemview,当view滑出屏幕时,不会销毁重建,而是复用旧的view,可以极高的提高性能;

2. 高度可定制

可以添加分割线、动画、拖拽、滑动删除;

3. 支持多种布局

支持线性、网格、瀑布流等布局实现;

子项的点击事件和长按点击事件

总体思路:因为我们在适配器的viewholder中可以拿到每个子项的view的,此时可以设置监听调用Onclick方法或者OnLongClick方法,然后通过接口回调的方式在RecycleView中设置回调的逻辑处理;

那么为什么要通过接口回调的方式呢?是因为适配器的任务就是绑定数据后显示UI,它不应该决定点击事件后的逻辑处理,所以在适配器中实现子项的监听,但是真正的实现我们放到Activity或者Fragment中,这样有利于解耦;

接下来看看具体的实现:

在适配器中:

private OnItemClickListener onItemClickListener;
public interface OnItemClickListener{void onItemClick(cityadapt cityadapt,int position);void onItemLongClick(cityadapt cityadapt,int position);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){this.onItemClickListener = onItemClickListener;
}
//实现接口,使得调用适配器中的Onclick的方法,然后再进行接口回调
public class cityviewholder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public cityviewholder(@NonNull View itemView) {super(itemView);itemView.setOnClickListener(this);
}@Overridepublic void onClick(View view) {if(onItemClickListener!= null){onItemClickListener.onItemClick(cityadapt.this,getAdapterPosition());}}@Overridepublic boolean onLongClick(View view) {return true;}
}

在实现类中

cityadapt1.setOnItemClickListener(new cityadapt.OnItemClickListener() {@Overridepublic void onItemClick(cityadapt cityadapt, int position) {viewPager2.setCurrentItem(position,true);}@Overridepublic void onItemLongClick(cityadapt cityadapt, int position) {}
});

在进行子项的删除和拖动的学习之前,得先了解一个类:ItemTouchHelper

ItemTouchHelper

  • ItemTouchHelper 是 Android 官方提供的一个 RecyclerView 辅助类

  • 它通过 监听手势事件,帮助我们轻松实现:
    Item 拖动(上下或左右移动)
    Item 滑动(左滑/右滑删除,或执行其他操作)

  • 不需要自己去写复杂的手势检测逻辑。

我理解的本质也是接口回调,我们只定义接口的实现,然后作为构造方法的参数传入ItemTouchHelper的实例中,最后与RecycleView绑定;

在这里我们定义回调后的实现,比如允许滑动的方向等等;

ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
}

然后通过ItemTouchHelper的实例传入,使得后续做出自定义的逻辑判断和反应等;

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);

最后通过attachToRecyclerView与recycleview绑定,binding.recyCity是recycleview的实例;

itemTouchHelper.attachToRecyclerView(binding.recyCity);

ItemTouchHelper.Callback中有必须实现的三个抽象方法:

  • getMovementFlags():用来指定支持的拖拽和滑动方向

  • onMove():拖拽时回调(交换两个 item 的位置)

  • onSwiped():侧滑时回调(比如删除 item)

在本模块中介绍一下`getMovementFlags()

//规定可以滑动的方向
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {int position = viewHolder.getAdapterPosition();if(position == 0){return 0;}int ver = 0;int hor = ItemTouchHelper.LEFT;return makeMovementFlags(ver,hor);
}
  • 最后返回一个方法makeMovementFlags(ver,hor),参数有两个,第一个是关于允许上下滑动或拖拽的,第二个是关于上下的;
int position = viewHolder.getAdapterPosition();
if(position == 0){return 0;
}

这里这么写得到当前滑动或者拖动的位置,如果这个是recycleview中第一个的话,就返回0,意味着不允许滑动或者拖拽;

  • ItemTouchHelper.LEFTItemTouchHelper.LEFTItemTouchHelper 里定义的一个常量,代表滑动(swipe)时允许的方向之一;

剩余的其他:

ItemTouchHelper.UP // 向上拖动

ItemTouchHelper.DOWN // 向下拖动

ItemTouchHelper.LEFT // 向左滑动

ItemTouchHelper.RIGHT // 向右滑动

子项的删除事件

ItemTouchHelper的基础上,我们还需重写一个方法:

//是否允许滑动移除@Overridepublic boolean isItemViewSwipeEnabled() {return true;}

然后在ItemTouchHelper中的onSwiped方法内规定逻辑;

           //规定左滑后的逻辑@Overridepublic void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {int i = viewHolder.getAdapterPosition();if(i != 0){cityadapt1.getData().remove(i);cityadapt1.notifyItemRemoved(i);
//                MainActivity.deleteFragment(i);addtomainweather.deleteFragment(i);}}

里面有三个方法:

  • cityadapt1.getData().remove(i) : 把适配器中持有的数据源里对应的 item 移除;

  • cityadapt1.notifyItemRemoved(i):触发删除的动画;

  • addtomainweather.deleteFragment(i):通过接口回调的方式,自定义实现删除的逻辑;

当然我们也可以定义删除的动画

子项删除事件的动画效果

代码如下:

public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){View view = viewHolder.itemView;Paint paint = new Paint();paint.setColor(Color.WHITE);if(dX < 0){c.drawRect((float) view.getRight()+dX,(float) view.getTop(),(float) view.getRight(),(float) view.getBottom(),paint);Bitmap icon = BitmapFactory.decodeResource(recyclerView.getContext().getResources(),R.drawable.deletecity);int iconmargin =( view.getHeight() - icon.getHeight())/2;int top = view.getTop()+iconmargin;int bottom = top + icon.getHeight();int left = view.getRight() - iconmargin - icon.getWidth();int right =  view.getRight() - iconmargin;c.drawBitmap(icon,null,new Rect(left,top,right,bottom),null);}}
}

这个方法是 ItemTouchHelper.Callback 提供的 onChildDraw,用来在 拖动/滑动时绘制额外的 UI 效果(比如背景、按钮、图标;

先看看这个方法对应的参数:

@NonNull Canvas c, // 画布

@NonNull RecyclerView recyclerView, // 当前的 RecyclerView

@NonNull RecyclerView.ViewHolder viewHolder, // 当前正在交互的 item

float dX, // X 方向的位移

float dY, // Y 方向的位移

int actionState, // 当前手势状态(滑动/拖动)

boolean isCurrentlyActive // 手指是否还在按住 item

代码中的部分说明:

actionState == ItemTouchHelper.ACTION_STATE_SWIPE是如果手势是滑动的话;

其他的滑动:

  • ItemTouchHelper.ACTION_STATE_IDLE → 没有操作

  • ItemTouchHelper.ACTION_STATE_DRAG → 拖动中

View view = viewHolder.itemView;获得当前的item;

c.drawRect((float) view.getRight()+dX,(float) view.getTop(),(float) view.getRight(),(float) view.getBottom(),paint); :里面有五个参数,分别是规定滑动后矩形的左边界,矩形的上边界,矩形的右边界,矩形的下边界,以及绘制的颜色/样式;

Bitmap icon = BitmapFactory.decodeResource(recyclerView.getContext().getResources(),R.drawable.deletecity);``recyclerView.getContext().getResources(),得到文件资源管理器,得到对应的图片等;
BitmapFactory.decodeResource(Resources res, int id)BitmapFactory是一个解码工具类,这个方法会读取资源文件,并转成内存中的 Bitmap 对象

c.drawBitmap(icon,null,new Rect(left,top,right,bottom),null);四个参数分别代表:设置到画布上的bitmap对象,源区域(null代表设置整张图片),以及你要放置的位置,设置透明度等;

子项的拖动事件

重写此方法:

//是否允许长按拖拽
@Override
public boolean isLongPressDragEnabled() {return true;
}

此处跟删除的逻辑差不多,解释放在注释中,可自行观看;

            @Overridepublic boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {//返回当前正在拖动的适配器中的数据索引int i = viewHolder.getAdapterPosition();//返回目标适配器中的数据索引int j = target.getAdapterPosition();//把适配器中持有的数据源里对应的 item 交换;Collections.swap(cityadapt1.getData(),i,j);//刷新item移动动画cityadapt1.notifyItemMoved(i,j);addtomainweather.swapFragment(i,j);return true;}

这样我们就可以实现子项的点击事件,删除,拖动啦;
–未完待续–

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

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

相关文章

AI驱动的软件测试:革命性的自动化、缺陷检测与实验优化

引言在当今快节奏的软件开发生命周期&#xff08;SDLC&#xff09;中&#xff0c;传统测试方法已逐渐无法满足对速度、覆盖面和准确性的极高要求。人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术的融入&#xff0c;正在从根本上重塑软件测试的格…

继续优化基于树状数组的cuda前缀和

在之前的博客《借助树状数组的思想实现cuda版前缀和》中&#xff0c;我们用三个kernel实现了基于树状数组的cuda版前缀和&#xff0c;但是在数据量较大时速度不如传统的reduce-then-scan方法&#xff0c;主要原因在于跨block的reduce阶段没有充分利用所有的cuda核心。在本博客中…

Qt图片资源导入

右键项目&#xff0c;点击添加新文件 选择Qt -> Qt Resource File 资源文件起名 如&#xff1a;res 生成res.qrc文件 在项目的同级目录下创建文件夹res&#xff0c;并将准备好的资源粘贴进去 右键qrc文件&#xff0c;选中Open in Editor 添加前缀 前缀是各种类型图片的分类&…

嵌入式第四十六天(51单片机(中断,定时器))

一.独立按键设置1.#include "key.h"void init_key(void) {P1 | (0x0F << 4); }int key_pressed(void) {static int ret 0;if((P1 & (1 << 4)) 0){ret 1;}else if((P1 & (1 << 5)) 0){ret 2;}else if((P1 & (1 << 6)) 0){r…

Visual Studio Code2024安装包及安装教程

一、软件下载软件名称&#xff1a;Visual Studio Code 2024安装环境&#xff1a;window10及以上系统下载链接&#xff1a;https://pan.quark.cn/s/d9831b28c69a解压软件Bandizip下载链接&#xff1a;https://pan.quark.cn/s/a54e79b5d553二、软件安装1、下载后&#xff0c;先解…

fps:游戏玩法

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录游戏玩法倒计时僵尸潮游戏成功&失败计时玩法&#xff1a;玩家在计时内存活&#xff0c;成功&#xff1b;反之失败Game界面&#xff1a;由关卡调用计时系统计时完成&#xff1a;调用结果界面结果界面玩家死亡&…

如何建立针对 .NET Core web 程序的线程池的长期监控

如何建立针对 .NET Core web 程序的线程池的长期监控 建立针对 .NET Core Web 应用程序线程池的长期监控是一个系统性的工程&#xff0c;它涉及代码集成、指标收集、存储、可视化和告警。 核心思路 线程池监控不是孤立的&#xff0c;它必须与应用程序的整体性能指标&#xff08…

前端开发学习路径

前端开发学习路径前端开发基础技能HTML、CSS和JavaScript是前端开发的三大核心技术。HTML用于构建网页结构&#xff0c;CSS负责样式设计&#xff0c;JavaScript实现交互功能。掌握这三项技术是学习前端开发的基础。现代前端开发通常需要了解ES6语法&#xff0c;包括箭头函数、解…

一款没有任何限制的免费远程手机控制手机的软件简介

这是一款没有任何限制的免费远程手机控制手机的软件支持安卓和苹果1.安装1.1被控制端安装airdroid1.2控制端air mirror2.登录同一个账号3.控制使用打开控制端软件选择要控制的机器直接点“远程控制“连接上后就可以任意操作被控手机了

在word中使用lateX公式的方法

非常好的问题&#xff01;这是一个许多科研人员和学生都渴望实现的功能。但需要明确的是&#xff1a; **Microsoft Word 本身并不具备“自动”将 LaTeX 代码实时转换为渲染后公式的功能。** 它不像 Overleaf 或 VS Code 的 Markdown 插件那样&#xff0c;输入 $Emc^2$ 就立刻变…

23种设计模式——代理模式(Proxy Pattern)详解

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a;设计模式 ✨特色专栏&#xff1a;知识分享 &#x…

webpack scope hositing 和tree shaking

Scope Hoisting&#xff08;作用域提升&#xff09; 和 Tree Shaking&#xff08;摇树优化&#xff09; 是现代前端构建中至关重要的概念。它们是构建工具&#xff08;如 Webpack、Rollup、Vite&#xff09;用来优化最终打包产物的核心技术。 核心概念快速理解 Tree Shaking&am…

手写React状态hook

在日常开发中&#xff0c;我们经常用到 React 的状态管理 Hook&#xff1a;useState 和 useReducer。 但你有没有想过&#xff1a;这些 Hook 内部是怎么实现的&#xff1f;为什么调用 setState 之后组件会重新渲染&#xff1f; 今天我们就来从零手写 useState 和 useReducer&am…

力扣hot100:相交链表与反转链表详细思路讲解(160,206)

问题描述核心思路&#xff1a;双指针交替遍历算法思想&#xff1a; 使用两个指针 pa 和 pb 分别从链表A和链表B的头节点出发&#xff0c;同步向后遍历。当任一指针走到链表末尾时&#xff0c;将其重定位到另一链表的头节点继续遍历。若两链表相交&#xff0c;pa 和 pb 最终会在…

跨平台游戏引擎 Axmol-2.8.1 发布

所有使用 axmol-2.8.0 的开发者都应更新至此版本 Axmol 2.8.1 版本是一个以错误修复和功能改进为主的次要 LTS 长期支持版本&#xff0c;发布时间: 2025 年 9 月 5 日 &#x1f64f;感谢所有对 axmol 项目的贡献者&#xff0c;包括财务赞助者&#xff1a;scorewarrior、peter…

通过PXE的方式实现Ubuntu 24.04 自动安装

PXE自动化安装Ubuntu 24.04的配置文件之前都是通过PXE来自动化安装Redhat系列的&#xff0c;例如&#xff1a;Rocky9、Rocky10、CentOS7、银河麒麟 Kylin-V10、Kylin-V11、OpenEuler 24.03等。现在安装Ubuntu系列的跟红帽的不太一样&#xff0c;所以在这里介绍下。创建三个文件…

AOSP Framework开发的一些超方便的快捷命令

在系统源码中发现的一些命令和快捷方式。我们在编译源码之前执行的source build/envsetup.sh,通过cat build/envsetup.sh发现如下命令 - lunch: lunch <product_name>-<build_variant>Selects <product_name> as the product to build, and <build_…

【Protues仿真】基于AT89C52单片机的数码管驱动事例

目录 0案例视频效果展示 1 AT89C52单片机驱动单个数码管 1.1 数码管基础知识 1.1.1外观与引脚 1.1.2 共阴(CC) vs 共阳(CA) 1.1.3段码表(以数字1为例) 1.1.4驱动方式A. 直连IO(最简单,占用IO多)一个段一根线,共阴或共阳公共端固定接GND/VCC。适合单个数码管、…

01-Redis 发展简史与核心定位解析:从诞生到三大产品矩阵

目录引言一、Redis 的起源与发展&#xff1a;从定制工具到开源生态二、Redis 的核心定位&#xff1a;不止是缓存的多面手三、Redis 三大产品矩阵&#xff1a;按需选择的完整解决方案3.1 Redis Open Source&#xff08;社区版&#xff09;&#xff1a;入门与轻量场景首选3.2 Red…

记录jilu~

centos1、安装最小版Linux 安装必要工具yum -install -y epel-releaseyum -install -y net-toolsyum -install -y vim2、修改hostname hostnamectl net-hostname newhostname3、网络配置文件&#xff0c;网关 &#xff0c; 使用ip &#xff0c;dns。。/etc/sysconfig/network-s…