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

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

RecyclerView基础

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

RecyclerView扩展

  • Android进阶之路 - ConcatAdapter到底有没有学习必要?

RecyclerView相关功能

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

那年花开

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

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

在这里插入图片描述

前置要求

包含数据结构视图结构

前置结构

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

package com.example.concatadatper

class 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">

    <TextView
        android: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">

    <TextView
        android: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.concatadatper

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class MoreViewAdapter(private val dataList: MutableList<MoreTypeBean>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    private val FIRST_TYPE = 1
    private val SECOND_TYPE = 2

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        //根据不同itemType加载不同的ViewHolder
        return 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: TextView

        init {
            firstText = itemView.findViewById<TextView>(R.id.tv_first)
        }
    }

    /**
     * 第二种视图类型
     * */
    class SecondViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var secondText: TextView

        init {
            secondText = itemView.findViewById<TextView>(R.id.tv_second)
        }
    }
}

使用方式

package com.example.concatadatper

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class 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.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.appcompat.widget.LinearLayoutCompat>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python笔记-设计模式】责任链模式

一、说明 旨在将请求沿着处理者链进行发送。收到请求后&#xff0c;每个处理者均可对请求进行处理&#xff0c;或将其传递给链上的下个处理者。 (一) 解决问题 将请求的发送者和接受者解耦&#xff0c;并使请求随着处理对象链传递&#xff0c;优化系统内部处理逻辑 (二) 使…

数据分析-Pandas数据探查初步:离散点图

数据分析-Pandas数据探查初步&#xff1a;离散点图 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff…

动态IP代理技术在网络爬虫中的实际使用

目录 前言 一、什么是动态IP代理技术&#xff1f; 二、动态IP代理技术的实际使用 1. 获取代理IP地址 2. 在网络爬虫中设置代理 3. 周期性更换代理 结论 前言 网络爬虫是一种通过自动化程序从互联网上获取数据的技术。然而&#xff0c;由于某些网站对爬虫进行限制&#…

120KW OBC充电机定期检测的必要性

随着电动汽车的普及&#xff0c;充电设备的需求也在不断增加&#xff0c;其中&#xff0c;120KW OBC&#xff08;On-Board Charger&#xff09;充电机作为电动汽车的重要充电设备&#xff0c;其性能和安全性直接关系到电动汽车的使用体验和安全。因此&#xff0c;对120KW OBC充…

使用vuetify实现全局v-alert消息通知

前排提示&#xff0c;本文为引流文&#xff0c;文章内容不全&#xff0c;更多信息前往&#xff1a;oldmoon.top 查看 简介 使用强大的Vuetify开发前端页面&#xff0c;结果发现官方没有提供简便的全局消息通知组件&#xff08;像Element中的ElMessage那样&#xff09;&#xf…

C# OpenCvSharp 颜色反转

目录 效果 灰度图 黑白色反转 彩色反转 项目 代码 下载 效果 灰度图 黑白色反转 彩色反转 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Te…

Go Run - Go 语言中的简洁指令

原文&#xff1a;breadchris - 2024.02.21 也许听起来有些傻&#xff0c;但go run是我最喜欢的 Go 语言特性。想要运行你的代码&#xff1f;只需go run main.go。它是如此简单&#xff0c;我可以告诉母亲这个命令&#xff0c;她会立即理解。就像 Go 语言的大部分功能一样&…

调用 科大讯飞机器翻译API 进行中英文翻译(超详细教程)

文章目录 1. 申请讯飞机器翻译API1.1 讯飞开放平台&#xff08;机器翻译&#xff09;1.2 点击免费试用后进入个人控制台界面1.3 点击购买字符量&#xff08;新用户首次免费200万字符&#xff09;1.4 回到个人控制台界面查看获得的字符量 2.推荐一个好用的Python库 [JioNLP]2.1 …

【java】14:final 关键字

基本介绍&#xff1a; Final01.java final中文意思:最后的,最终的. final可以修饰类、属性、方法和局部变量. 在某些情况下,程序员可能有以下需求&#xff0c;就会使用到final:1当不希望类被继承时,可以用final修饰.【案例演示】 2)当不希望父类的某个方法被子类覆盖/重写(over…

什么是SSH端口转发?

目录 前言&#xff1a; 一、SSH端口转发的概念 二、SSH端口转发的类型 2.1 本地端口转发 2.2 远程端口转发 2.3 动态端口转发 三、SSH端口转发的用途 3.1 安全远程访问 3.2 跨越网络限制 3.3 加密流量传输 3.4 跨越 NAT 网络 3.5 安全代理 四、总结 前言&#xff…

现代信号处理学习笔记(二)参数估计理论

参数估计理论为我们提供了一套系统性的工具和方法&#xff0c;使我们能够从样本数据中推断总体参数&#xff0c;并评估估计的准确性和可靠性。这些概念在统计学和数据分析中起着关键的作用。 目录 前言 一、估计子的性能 1、无偏估计与渐近无偏估计 2、估计子的有效性 两个…

基于深度学习的故障诊断GAN之生成对抗网络

这个图是作者当时研究CGAN画的&#xff0c;从代码流程来看&#xff0c;GAN和CGAN是一样的&#xff0c;两者的区别在于&#xff0c;GAN输入噪声和原始图片&#xff0c;CGAN输入噪声、条件信息&#xff08;标签&#xff09;和原始图片&#xff0c;大家可以仔细研究代码&#xff0…

P0故障应对策略之:为什么P0故障难以排查

与大模型探讨P0故障 P0级故障&#xff0c;作为系统中最严重的故障&#xff0c;它们的发生往往带来灾难性的后果和巨大的损失。同时&#xff0c;这类故障的排查与修复也往往复杂而棘手&#xff0c;对整个团队的经验、综合能力、应急处置流程都是巨大的挑战。 排查P0级故障的过程…

简单实现文字滚动效果-CSS版本

先看看效果 话不多说直接上代码 <template><div class"main"><div class"scroll-region"><div class"swiper-scroll-content"><span class"list-btn" v-for"(item, index) in overviewList" :…

IDEA中 @SpringBootApplication 多个注解无法引入依赖

终于解决了&#xff01;&#xff01;&#xff01; cd到报红项目的根目录&#xff0c;然后输入mvn idea:idea就行了。

新的一年,如何优化企业库存管理?

随着社会的发展和经济的不断增长&#xff0c;库存管理成为了企业运营中非常重要的一环。库存作为企业的资产之一&#xff0c;直接影响着企业的盈利能力和竞争优势。因此&#xff0c;对企业库存进行科学的分析和管理&#xff0c;成为了确保企业持续稳定发展的必要手段之一。企业…

为什么深度学习的效果更好?

导 读 深度学习是机器学习的一个子集&#xff0c;已成为人工智能领域的一项变革性技术&#xff0c;在从计算机视觉、自然语言处理到自动驾驶汽车等广泛的应用中取得了显着的成功。 深度学习的有效性并非偶然&#xff0c;而是植根于几个基本原则和进步&#xff0c;这些原则和进…

spring框架Bean的作用域?对需要保持会话状态的bean应使用prototype作用域?为啥?

当一个bean被定义为"prototype"作用域时&#xff0c;每次请求该bean时都会创建一个新的实例&#xff0c;而不是像"singleton"作用域那样共享同一个实例。 对于需要保持会话状态的bean&#xff0c;如果使用"singleton"作用域&#xff0c;会导致所…

Dubbo知识点大全

“ 分布式应用场景有高并发,高可扩展和高性能的要求。还涉及到,序列化/反序列化,网络,多线程以及设计模式的问题。幸好 Dubbo 框架将上述知识进行了封装,让程序员能够把注意力放到业务上。 概念和架构 Provider:暴露服务的服务提供方Consumer:调用远程服务消费方Regist…

Linux系统---nginx(1)服务

目录 一.Nginx概述 1.定义 2.Nginx模块作用 &#xff08;1&#xff09;main模块 &#xff08;2&#xff09;stream服务模块 &#xff08;3&#xff09;邮件服务模块 &#xff08;4&#xff09;第三方模块 &#xff08;5&#xff09;events模块 &#xff08;6&#xff0…