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

【Android】RecyclerView循环视图(2)——动态加载数据

在这里插入图片描述
三三要成为安卓糕手

一:在适配器中设置item布局数据

1:ViewHolder中找控件

提问:我们都是设置的相同的数据,怎么样为每一个item设置不同的数据

第一反应去view中查找控件,但是我们已经把view交给ViewHolder管理了,所以应该去ViewHolder中查找

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不在这里

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2:设置数据

提问:控件找到了,在哪设置数据?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意:这里的ivPicture,tvTitle是在构造方法中;把它们设置为MyViewHolder中的成员变量,便于onBindViewHolder方法中使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3:设置数据优化版本

这件设置数据的事情还能变得更加简单一点

(1)Adapter泛型源码

带着泛型,是继承自ViewHolder的类型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果声明为泛型,那么我们下面重写的方法中的返回类型也会被约束

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

也不用做强制转换了,直接使用holder即可

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(2)效果如下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二:在Adapter中添加动态数据

夺命连环第三问:数据生效了,数据是固定的,怎么样把数据写活呢?

在一个列表中可能会有数十上百条数据,优先方案使用一个容器来保存这些图片,主题,标题

1:创建Article类

生成get和set方法,注意带三个参数的构造方法

package com.xlong.myapplication.recyclerview;public class Article {private String title;//标题private String desc;//描述private String author;//作者private long publish;//发布时间private int picture;//图片资源public Article(String title, String author, int picture) {this.title = title;this.author = author;this.picture = picture;}public int getPicture() {return picture;}public void setPicture(int picture) {this.picture = picture;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public long getPublish() {return publish;}public void setPublish(long publish) {this.publish = publish;}
}

2:创建容器

构造方法

    public ArticleAdapter(){articles = createData();Log.i(TAG, "ArticleAdapter: articles.size = " + articles.size());}

不要在构造方法中无脑添加新闻文章数据,这里创建一个createData方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3:createData方法

    /*** 自己造一点数据给RecyclerView** @return 返回一个存放20条数据的新闻列表*/private ArrayList<Article> createData() {ArrayList<Article> articles = new ArrayList<>();articles.add(new Article("辽宁清原抽水蓄能电站最后一台定子吊装完成","人民网-图片频道,供稿:人民资讯", R.drawable.ic_article_1));articles.add(new Article("通行时间再缩短!广湛高铁佛山站建设正式启动","人民网-广东频道,供稿:人民资讯", R.drawable.ic_article_2));articles.add(new Article("19岁杭州帅小伙第一名,还有人抓到一只甲鱼!今早3000多人在钱塘江边,太欢乐了","杭州网", R.drawable.ic_article_3));articles.add(new Article("今日起“两江小渡”航线恢复正常运营","上游新闻", R.drawable.ic_article_4));articles.add(new Article("中国太保小排球夏令营在漳州火热启航","国际时事讲解", R.drawable.ic_article_5));articles.add(new Article("奋力推动民族地区高质量发展和现代化建设迈出新步伐","当代先锋网", R.drawable.ic_article_6));articles.add(new Article("相信青春的力量|写在我省2024年万名大学生志愿服务西部计划出征之际","人民网-图片频道,供稿:人民资讯", R.drawable.ic_article_7));articles.add(new Article("量身定制“海外订单” 贵州汽车制造开拓国际市场","当代先锋网", R.drawable.ic_article_8));articles.add(new Article("势不可挡……在这里,乡村振兴的新引擎正发出强劲动力","鲁网", R.drawable.ic_article_9));articles.add(new Article("菏泽职业学院召开2024届毕业生第二轮就业核查工作部署会","大众报业·齐鲁壹点", R.drawable.ic_article_10));articles.add(new Article("菏泽职业学院学前教育系(育中教育学院)斩获省级大赛一等奖","西安快线", R.drawable.ic_article_11));articles.add(new Article("菏泽职业学院一类教学大赛,二等奖+2!","大众报业·齐鲁壹点", R.drawable.ic_article_12));articles.add(new Article("中央气象台停止对“格美”编号 湖南辽宁吉林等地仍有强降雨","国际时事讲解", R.drawable.ic_article_13));articles.add(new Article("习水仙源镇:清凉山水引客来 消夏避暑人气足","多彩贵州网", R.drawable.ic_article_14));articles.add(new Article("习水县寨坝镇:清凉避暑地 康养第二乡","多彩贵州网", R.drawable.ic_article_15));articles.add(new Article("赤水市元厚镇:新品荔枝出山记","人民网-图片频道,供稿:人民资讯", R.drawable.ic_article_16));articles.add(new Article("习水三岔河镇小小错车道 畅通出行暖民心","湖南日报", R.drawable.ic_article_17));articles.add(new Article("习水土城镇社会实践活动丰富学生假期生活","上海咨询", R.drawable.ic_article_18));articles.add(new Article("赤水建强“小站点”释放乡村振兴新动能","福建新闻网,供稿:人民资讯", R.drawable.ic_article_19));articles.add(new Article("习水同民镇:火龙果喜丰收 果农笑开颜","上游新闻,供稿:人民资讯", R.drawable.ic_article_20));return articles;}

类成员变量articles和createData方法内的局部变量articles指向的是同一个内存地址

三:动态数据和布局做关联

1:position

当前触发onBindVIewHolder方法的位置

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

打印个日志观察一下position——每一条item都有位置0,1,2,3,4

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每次item被绘制的时候都会触发一次onBindViewHolder方法,并且位置也会随之变化,而我们的ArrayList的index索引也是从0开始,所以我们可以利用索引这一点作为桥梁,让holder取到ArrayList中的数据

     /***  有一条item就调用一次这个方法*  数据如何与item布局做关联*/@Overridepublic void onBindViewHolder(@NonNull ArticleAdapter.MyViewHolder holder, int position) {Log.i(TAG, "onBindViewHolder: position" + position);
//        MyViewHolder myViewHolder = (MyViewHolder)holder;//        holder.ivPicture.setImageResource(R.drawable.icon_wechat);
//        holder.tvTitlet.setText("我是在Java中指定的title标题!!!");
//        holder.tvAuthor.setText("我是作者");Article article = articles.get(position);holder.ivPicture.setImageResource(article.getPicture());holder.tvTitlet.setText(article.getTitle());holder.tvAuthor.setText(article.getAuthor());}

2:getItemCount

知道这个方法的作用是返回 RecyclerView 中的 item 总数

如果显示的条数多余我们有的数据呢?就会越界

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

优雅写法

    /*** @return  告诉RecyclerView显示多少条数据*/@Overridepublic int getItemCount() {
//        if (articles != null){
//            return articles.size();
//        }else {
//            return 0;
//        }return articles == null ? articles.size() : 0;}

总结:核心执行流程

ArticleListActivity.onCreate()  
→ 加载布局 → 获取RecyclerView  
→ 设置LinearLayoutManager  
→ new ArticleAdapter(设置适配器,初始化数据)
->ArticleAdapter类构造方法中创建数据  
→ RecyclerView与Adapter绑定  → getItemCount() → 返回数据总数(20) 适配器就会选择显示20条数据 → onCreateViewHolder() → 创建列表项视图和ViewHolder(按需创建,如5次)  → onBindViewHolder() → 为每个位置绑定数据(执行20次)  
→ 列表显示,滚动时复用ViewHolder并重新绑定数据  

四:模拟数据滞后加载场景

实际上很多场景下,RecycleView不是说一创建好,这些数据就存在了,而是经过了一段时间,我们的recycleView才会被创建好

这里我们使用一个点击按钮,当点击按钮后,我们才把这些数据进行展示,模拟数据滞后性

1:加载数据

在点击按钮后,调用createData方法创建数据

<Buttonandroid:id="@+id/btn_load"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="加载数据"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" />
		//点击加载数据按钮,加载数据;目的:模拟数据的延迟效果findViewById(R.id.btn_load).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {ArrayList<Article> articles = createData();adapter.setArticles(articles);}});

在ArticleAdapter中创建set方法

public void setArticles(ArrayList<Article> articles) {this.articles = articles;//告诉adapter,关联的数据源有变化,请重新根据数据做出调整notifyDataSetChanged();Log.i(TAG, "setArticles: article.size = " + articles.size());}

(1)notifyDataSetChanged

问题引入:现在点击按钮是没有反应的,没有数据的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分析:我们仅仅是改变了这个容器中的数据,但是Adapter适配器本身不知道容器中数据更新了,size不为0了,所以需要调用notifyDataSetChanged();提醒RecyclerView.Adapter刷新一下信息(像极了村里才通网)

总结:数据需要更新的场景下,一般都会用到notifyDataSetChanged这个方法

2:修改数据

列表的某一个部分发生了变化,也可以用notify,这里我们同样用模拟的方法演示

    <Buttonandroid:id="@+id/btn_modify"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="修改部分"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="parent" />
        findViewById(R.id.btn_modify).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {ArrayList<Article> articles = adapter.getArticles();Article article = articles.get(1);article.setTitle("我修改了第二条数据的标题");
//                adapter.notifyDataSetChanged();//不必全部刷新adapter.notifyItemChanged(1);}});

在ArticleAdapter中创建get方法

public ArrayList<Article> getArticles() {return articles;
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(1)notifyItemChanged

对单条数据进行刷新而非全部,这里节约了资源和提高了性能

Adapter中也提供了很多其他的刷新方法,了解即可

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3:删除数据

    <Buttonandroid:id="@+id/btn_remove"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="删除"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent" />
		findViewById(R.id.btn_remove).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {ArrayList<Article> articles = adapter.getArticles();Log.i(TAG, "onClick: 初始article size = " + articles.size());articles.remove(2);adapter.notifyItemRemoved(2);ArrayList<Article> articles1 = adapter.getArticles();Log.i(TAG, "onClick: 删除后article size = " + articles1.size());}});

(1)数据源ArrayList和Adapter同步删除

问题来了:删除一个item后,数据源的size大小依旧是20;第一次删除是有效果的,全局列表刷新,第二次就没效果了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分析:因为数据源本身还是20条数据,没有发生变化。他就会重新的根据数据源来匹配怎么显示

解决方案:对某个列表做移除或者插入数据时候,要先对数据源做一次操作;这样才能保证数据的一致性

其实就是先对ArrayList(数据源)做一次移除操作,再对Adapter做一次移除操作

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总结:对RecyclerView的数据做增删查改操作的时候,记住同时也要处理数据源

http://www.lryc.cn/news/608815.html

相关文章:

  • 【C 学习】04-了解变量
  • 《volatile 与 synchronized 底层实现与性能比较》
  • 【OD机试题解法笔记】文件缓存系统
  • linux 扩展未分配的磁盘空间到home下
  • 【从零开始速通C语言1】 - 汇编语言1
  • RAG 知识库实战指南:基于 Spring AI 构建 AI 知识问答应用
  • 第N个泰波那契数
  • Coze 打通飞书多维表格,实现数据增删改查操作实战详解
  • 机器学习sklearn:支持向量机svm
  • 《使用Qt Quick从零构建AI螺丝瑕疵检测系统》——9. 接入真实硬件:驱动USB摄像头
  • 李宏毅深度学习教程 第8-9章 生成模型+扩散模型
  • 【Unity3D实例-功能-镜头】俯视角
  • JVM-垃圾回收器与内存分配策略详解
  • [创业之路-530]:创业公司五维架构设计:借鉴国家治理智慧,打造敏捷型组织生态
  • 智变时代:AI 如何重构工作边界与行业生态?
  • 【MySQL安全】什么是SQL注入,怎么避免这种攻击:前端防护、后端orm框架、数据库白名单
  • 计算机网络:如何在实际网络中进行子网划分
  • 从零开始学Express,理解服务器,路由于中间件
  • C#模式匹配用法与总结
  • Supergateway教程
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现各类垃圾的分类检测识别(C#代码UI界面版)
  • 玩转 Playwright 有头与无头模式:消除差异,提升爬虫稳定性
  • LLM - 智能体工作流设计模式
  • 小红书开源dots.ocr:单一视觉语言模型中的多语言文档布局解析
  • 【设计模式】5.代理模式
  • [LeetCode优选算法专题一双指针——有效三角形的个数]
  • Python 程序设计讲义(60):Python 的函数——递归函数
  • 从“配置地狱”到“云端乐园”——Nacos 如何成为分布式微服务配置中心的“定海神针”
  • 【MySQL】MySQL中锁有哪些?
  • ethtool,lspci,iperf工具常用命令总结