为什么我不能使用数据类的字段作为jetpack compose中lazyColumn的item的key?

问题描述 投票:0回答:1

一个非常非常简单的例子(implementation(platform("androidx.compose:compose-bom:2023.08.00"))):

package com.study.myapplication

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.study.myapplication.ui.theme.MyApplicationTheme

data class Id(val level: Int, val index: Int)

class Man(val id: Id, val name: String)

val men = listOf(
    Man(Id(1, 1), "Amy"),
    Man(Id(1, 2), "Bob")
)

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting(men)
                }
            }
        }
    }
}

@Composable
fun Greeting(men: List<Man>, modifier: Modifier = Modifier) {
    LazyColumn (modifier = modifier) {
        items(men, key = { it.id.index }) {   // <- render problem
        //items(men, key = { it.id }) {       // <- okay
            Text(it.name)
        }
    }
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    MyApplicationTheme {
        Greeting(men)
    }
}

参考代码中的注释: 如果我使用 man.Id.index 作为键,它呈现正常。 如果我使用 man.Id 作为 key,会提示渲染问题。

在物理设备中,我找到了真正的原因:

java.lang.IllegalArgumentException: Type of the key Id(level=1, index=1) is not supported. On Android you can only use types which can be stored inside the Bundle.

为什么?

android-jetpack lazycolumn
1个回答
0
投票

当您使用

it.id.index
作为键时,您本质上是在使用
Int
值,它是一种可以轻松存储在
Bundle
中的原始类型。但是,当您使用
it.id
时,您正在尝试使用自定义
data class
id
,它不能直接存储在
Bundle
中,因为它不是原始类型,也不是实现
Parcelable
的类型。

因此,如果需要,您可以利用

Parcelable

@Parcelize
data class Id(val level: Int, val index: Int): Parcelable

不要忘记添加

kotlin-parcelize
插件到 build.gradle

plugins {
    id("kotlin-parcelize")
}
© www.soinside.com 2019 - 2024. All rights reserved.