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

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

RecyclerView基础

RecyclerView扩展

RecyclerView相关功能

那年花开

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

前置要求

包含数据结构视图结构

前置结构

问:在列表中你如何判断某条数据加载对应视图?

答:不论如何,数据结构中一定有一个类似type的字段用于区分展示哪种类型的视图

kotlin 复制代码
package com.example.concatadatper

class MoreTypeBean(var data: String, var type: Int)

前置视图

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

Tip

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

item_first (视图类型一)

xml 复制代码
<?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 复制代码
<?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方法,从而加载不同的视图,处理不同的逻辑,具体如下

kotlin 复制代码
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)
        }
    }
}

使用方式

kotlin 复制代码
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 复制代码
<?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>
相关推荐
长亭外的少年7 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿9 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神10 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛11 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法11 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter12 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快13 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl14 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
麦田里的守望者江14 小时前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
Dnelic-14 小时前
解决 Android 单元测试 No tests found for given includes:
android·junit·单元测试·问题记录·自学笔记