You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Android Compose类型安全导航传递列表报错:找不到对应NavType

解决Compose类型安全导航传递自定义对象列表的报错问题

报错核心原因

报错Route ... could not find any NavType for argument list of type kotlin.collections.ArrayList - typeMap received was {}的本质是:Java的ArrayList类型在Kotlin类型系统与Compose导航的参数解析逻辑中存在匹配兼容性问题,导致你注册的typeMap未被导航框架正确识别——尽管SavedStateHandle已能拿到序列化后的字符串数据,但导航框架在参数反序列化阶段无法匹配到对应的NavType

具体解决步骤

1. 替换路由参数类型为Kotlin标准List

修改导航目标定义,将ArrayList替换为Kotlin的List(序列化与反序列化会自动兼容,无需额外处理):

@Serializable
data class FirstLoginScreen2(val list: List<PropertyTagNavigation>)

2. 调整自定义NavType的泛型类型

更新CustomNavType的实现,将泛型从ArrayList<PropertyTagNavigation>改为List<PropertyTagNavigation>

val List = object : NavType<List<PropertyTagNavigation>>(isNullableAllowed = false) {
    override fun get(bundle: Bundle, key: String): List<PropertyTagNavigation>? {
        return bundle.getString(key)?.let { Json.decodeFromString(it) }
    }

    override fun parseValue(value: String): List<PropertyTagNavigation> {
        return Json.decodeFromString(Uri.decode(value))
    }

    override fun serializeAsValue(value: List<PropertyTagNavigation>): String {
        return Uri.encode(Json.encodeToString(value))
    }

    override fun put(bundle: Bundle, key: String, value: List<PropertyTagNavigation>) {
        bundle.putString(key, Json.encodeToString(value))
    }
}

3. 更新导航目的地的typeMap配置

typeMap中的typeOf参数改为匹配KotlinList的类型:

composable<OwnerGraph.FirstLogin.FirstLoginScreen2>(
    typeMap = mapOf(
        typeOf<List<PropertyTagNavigation>>() to CustomNavType.List,
    )
)

4. ViewModel代码无需修改

原ViewModel中从SavedStateHandle获取数据的逻辑保持不变,因为ArrayList可以自动转换为KotlinList,不会影响后续的toPropertyTag()调用。

补充说明

导航框架的参数解析分为两个独立阶段:

  1. 序列化参数并存入Bundle(这一步已完成,所以SavedStateHandle能拿到数据)
  2. 根据路由参数类型匹配NavType进行反序列化(这一步因为ArrayList的类型匹配失败,导致报错)

使用Kotlin标准List可以避免Java集合类型与Kotlin类型系统的交互问题,确保typeMap能被导航框架正确识别。

内容的提问来源于stack exchange,提问作者No_Name

火山引擎 最新活动