当前位置: 首页 > 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.dtcms.com/a/312812.html

相关文章:

  • IntelliJ IDEA开发编辑器摸鱼看股票数据
  • git用户设置
  • LangChain4J入门:使用SpringBoot-start
  • 【abc417】E - A Path in A Dictionary
  • template<typename R = void> 意义
  • 2. 字符设备驱动
  • LeetCode Hot 100,快速学习,不断更
  • #C语言——刷题攻略:牛客编程入门训练(四):运算
  • Kazam产生.movie.mux后恢复视频为.mp4
  • 小宿科技:AI Agent 的卖铲人
  • zookeeper持久化和恢复原理
  • idea中.xml文件的块注释快捷键
  • Hugging Face 模型文件介绍
  • IDEA查看源码利器XCodeMap插件
  • 【高等数学】第七章 微分方程——第八节 常系数非齐次线性微分方程
  • 【lucene】ByteBuffersIndexInput
  • k8s日志收集
  • Redis面试精讲 Day 8:Stream消息队列设计与实现
  • 对接古老系统的架构实践:封装混乱,走向有序
  • [硬件电路-146]:模拟电路 - DCDC与LDO详解、常见芯片、管脚定义
  • 基于 LangChain + 通义千问 + bge-large 中文 Embedding 搭建一个RAG问答示例
  • TVS二极管数据手册解读
  • 【lucene】ByteBufferGuard
  • Android 之 MVVM架构
  • 【MySQL】MySQL中锁有哪些?
  • Flutter 函数的基本使用
  • day39 力扣198.打家劫舍 力扣213.打家劫舍II 力扣337.打家劫舍 III
  • 常见框架漏洞靶场攻略
  • Java 实现poi方式读取word文件内容
  • 力扣967:连续差相同的数字