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

Android基础进阶 - RecyclerView列表加载多类型视图

你是否会经常见到在同一个 RecyclerView 列表中加载多种不同的布局效果?最近写了一篇 ConcatAdapter 相关内容,发现虽然之前一直在使用多类型视图列表,但从未记录过,故重新记录于此

RecyclerView基础

  • Android进阶之路 - RecyclerView基础使用(17年)
  • Android进阶之路 - RecyclerView实现横、纵向滑动列表(19年)

RecyclerView相关功能

  • Android进阶之路 - RecyclerView左划删除(SwipeRecyclerView的简单使用 17年)
  • Android进阶之路 - RecyclerView列表置顶、滑动到指定条目(18年)
  • Android进阶之路 - RecyclerView列表自动无限水平滚动(21年)
  • Android进阶之路 - 双列表联动效果(18年)

那年花开

    • 前置要求
      • 前置结构
      • 前置视图
    • 核心实现
    • 使用方式

实现效果(不同背景色代表不同 ViewType 视图)

在这里插入图片描述

前置要求

包含数据结构视图结构

前置结构

问:在列表中你如何判断某条数据加载对应视图?
答:不论如何,数据结构中一定有一个类似type的字段用于区分展示哪种类型的视图

package com.example.concatadatperclass MoreTypeBean(var data: String, var type: Int)

前置视图

列表中有几种视图类型,一般就意味着有几种对应的 layout布局ViewHolder

Tip

  • 为了更直观查看实现效果,简化了视图类型对应的 layout 布局
  • 当前不同类型的ViewHolder写在了Adapter中,如有需求也可以抽出来

item_first (视图类型一)

<?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="50dp"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:background="#f65478"android:textColor="#ffffff"android:id="@+id/tv_first"android:text="First" />
</LinearLayout>

item_second(视图类型二)

<?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="50dp"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:background="#e98745"android:textColor="#ffffff"android:id="@+id/tv_second"android:text="Second" />
</LinearLayout>

核心实现

常规的多类型视图列表, RecyclerView 一般只有一个 Adapter,通过重写内部 onCreateViewHolderonBindViewHoldergetItemViewType方法,从而加载不同的视图,处理不同的逻辑,具体如下

package com.example.concatadatperimport android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerViewclass MoreViewAdapter(private val dataList: MutableList<MoreTypeBean>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {private val FIRST_TYPE = 1private val SECOND_TYPE = 2override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {//根据不同itemType加载不同的ViewHolderreturn if (viewType == FIRST_TYPE) {val firstView = LayoutInflater.from(parent.context).inflate(R.layout.item_first, parent, false)FirstViewHolder(firstView)} else {val secondView = LayoutInflater.from(parent.context).inflate(R.layout.item_second, parent, false)SecondViewHolder(secondView)}}override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {//不同的视图类型,逻辑也有所不同val currentInfo = dataList[position]if (currentInfo.type == FIRST_TYPE) {(holder as FirstViewHolder).firstText.text = currentInfo.data} else {(holder as SecondViewHolder).secondText.text = currentInfo.data}}override fun getItemCount(): Int {return dataList.size}/*** Tip:记得重写该处逻辑,否则onCreateViewHolder返回可能有问题* */override fun getItemViewType(position: Int): Int {return dataList[position].type}/*** 第一种视图类型* */class FirstViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {var firstText: TextViewinit {firstText = itemView.findViewById<TextView>(R.id.tv_first)}}/*** 第二种视图类型* */class SecondViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {var secondText: TextViewinit {secondText = itemView.findViewById<TextView>(R.id.tv_second)}}
}

使用方式

package com.example.concatadatperimport android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerViewclass MainActivity : AppCompatActivity() {private var totalList: MutableList<MoreTypeBean> = mutableListOf<MoreTypeBean>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)//数据模拟(当前有1、2俩种类型,对应的背景色)totalList.add(MoreTypeBean("窗前明月光", 1))totalList.add(MoreTypeBean("昨日已熬夜", 2))totalList.add(MoreTypeBean("老夫思故乡", 1))totalList.add(MoreTypeBean("今日又熬夜", 2))totalList.add(MoreTypeBean("明日得早睡", 2))//视图关联val mRv = findViewById<RecyclerView>(R.id.rv)val moreViewAdapter = MoreViewAdapter(totalList)mRv.layoutManager = LinearLayoutManager(this)mRv.adapter = moreViewAdapter}
}

activity_main

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv"android:layout_width="match_parent"android:layout_height="match_parent" />
</androidx.appcompat.widget.LinearLayoutCompat>

相关文章:

  • IT廉连看——Uniapp——页面样式与布局
  • NUS神经网络生成我感觉解读过于夸大了
  • Git 报错:unable to update local ref
  • 【Vue】组件通信组件通信
  • 树结构数据
  • 2步破解官方sublime4
  • CSS 入门手册(一)
  • 【Python】Ubuntu创建虚拟环境运行Python
  • java面试题之mybatis篇
  • 学习pybind11:Hello World例子
  • Linux学习第二天(yum、vim工具)
  • 自定义焊件轮廓库的方法
  • FFMPEG 推流至 NGINX-RTMP 服务
  • React PureComponent 和 React.memo()区别
  • 各平台,各语言基础数据类型占用字节比较
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 10个确保微服务与容器安全的最佳实践
  • 77. Combinations
  • Bootstrap JS插件Alert源码分析
  • canvas 高仿 Apple Watch 表盘
  • classpath对获取配置文件的影响
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • redis学习笔记(三):列表、集合、有序集合
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • Vue.js源码(2):初探List Rendering
  • 官方解决所有 npm 全局安装权限问题
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 记一次用 NodeJs 实现模拟登录的思路
  • 解决iview多表头动态更改列元素发生的错误
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 免费小说阅读小程序
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 用Python写一份独特的元宵节祝福
  • 优化 Vue 项目编译文件大小
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • MPAndroidChart 教程:Y轴 YAxis
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 带你开发类似Pokemon Go的AR游戏
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • #stm32整理(一)flash读写
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (4)(4.6) Triducer
  • (function(){})()的分步解析
  • (Python第六天)文件处理
  • (SpringBoot)第七章:SpringBoot日志文件
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (四)Linux Shell编程——输入输出重定向
  • .NET 中让 Task 支持带超时的异步等待
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题