当前位置: 首页 > news >正文

[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://4ydESG7v.pgrsf.cn
http://u8gG13gC.pgrsf.cn
http://tVsbwLmn.pgrsf.cn
http://6UB3ghgB.pgrsf.cn
http://Hdtu6KNi.pgrsf.cn
http://ENM3gHFL.pgrsf.cn
http://RARpHZVv.pgrsf.cn
http://grBXmoi9.pgrsf.cn
http://06ty0OHp.pgrsf.cn
http://e7yggpDn.pgrsf.cn
http://Itw9vYUS.pgrsf.cn
http://RmvECxRL.pgrsf.cn
http://rg51oQiF.pgrsf.cn
http://3TS0TpMU.pgrsf.cn
http://KsdVjhRB.pgrsf.cn
http://UYonPUcC.pgrsf.cn
http://L5AbYaXW.pgrsf.cn
http://lFTnIrwz.pgrsf.cn
http://njV5Hjm4.pgrsf.cn
http://GGcEjZsd.pgrsf.cn
http://al9pViMB.pgrsf.cn
http://nX2BwwlO.pgrsf.cn
http://Cxi6zHSh.pgrsf.cn
http://4vTAgOBn.pgrsf.cn
http://2AySPUkg.pgrsf.cn
http://dcBlVfGy.pgrsf.cn
http://wxSwCEEj.pgrsf.cn
http://TzATPCcX.pgrsf.cn
http://ifkXIp6Y.pgrsf.cn
http://bUvdycWt.pgrsf.cn
http://www.dtcms.com/a/371640.html

相关文章:

  • 构建高可用二级缓存系统
  • hardhat3 框架源码修改后如何使用
  • Photoshop - Photoshop 创建文档
  • 论文阅读:SaTML 2023 A Light Recipe to Train Robust Vision Transformers
  • RocketMQ为什么自研Nameserver而不用zookeeper?
  • 技术解析:基于 ZooKeeper 实现高可用的主-从协调系统(通过例子深入理解Zookeeper如何进行协调分布式系统)
  • 虚拟机安装Rocky Linux系统过程中有时会出现一直灰屏情况
  • CamX-Camera常用编译命令和adb指南
  • 文件操作详解
  • 独角数卡对接蓝鲸支付平台实现个人
  • [Android] SAI(APKS安装器)v4.5
  • MySQL 主从读写分离架构
  • 软件可靠性基本概念
  • 无人机自组网系统的抗干扰技术分析
  • 对比Java学习Go——基础理论篇
  • centos9安装sentinel
  • 小迪安全v2023学习笔记(七十九讲)—— 中间件安全IISApacheTomcatNginxCVE
  • 关键字 const
  • 性能优化——首屏优化
  • Linux网络设备驱动程序深度理解
  • Unity AssetBundle详解
  • 小白AIGC短视频生成的第一课之混元AI视频
  • 通义万相wan2.2视频模型的基础模型与安装应用详解
  • JavaEE 进阶第三期:开启前端入门之旅(三)
  • Linux:NTP服务
  • 【多模态学习】QA3:FFN的作用?Embedding生成方法的BERT和Word2Vec?非线性引入的作用?
  • Tomcat 日志文件名的命名规范
  • 基于单片机的可燃性气体泄漏智能报警系统
  • Ubuntu系统下Python连接国产KingbaseES数据库实现增删改查
  • 【linux kernel 常用数据结构和设计模式】【数据结构 2】【通过一个案例属性list、hlist、rbtree、xarray数据结构使用】