You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Observer响应区分:解决产品列表混入分类列表问题

问题分析与解决方案

你的问题核心是分类和产品数据共用了同一个数据源集合,或者addCategories()、addProducts()方法没有做数据隔离,导致产品数据被追加到分类列表里,最终Adapter把两类数据混在一起展示。以下是具体解决思路和代码修改示例:


1. 核心修复思路

  • 给分类、产品数据定义独立的数据源集合,避免数据交叉污染;
  • 如果需要在同一个列表展示两类数据(比如分类作为标题、产品作为子项),使用多类型Adapter区分数据类型;
  • 如果是分开展示(比如两个独立的RecyclerView),分别给两类数据绑定对应的Adapter。

2. 代码修改示例

场景1:分开展示两个独立列表(推荐,逻辑更清晰)

// 初始化分类列表和Adapter
private val categoryList = mutableListOf<Category>()
private val categoryAdapter = CategoryAdapter(categoryList)

// 初始化产品列表和Adapter
private val productList = mutableListOf<Product>()
private val productAdapter = ProductAdapter(productList)

// 监听分类数据
viewModel.getCategories().observe(viewLifecycleOwner) {
    if (it.error.isNotEmpty()) {
        Toast.makeText(context, it.error, Toast.LENGTH_LONG).show()
    } else if (it.success.isNotEmpty()) {
        val categoriesList = it.success as ArrayList<Any>
        val categories = viewModel.getCategoriesList(categoriesList)
        // 清空旧数据,添加新分类,通知Adapter更新
        categoryList.clear()
        categoryList.addAll(categories)
        categoryAdapter.notifyDataSetChanged()
    }
}

// 监听产品数据
viewModel.getProducts(1).observe(viewLifecycleOwner) {
    if (it.error.isNotEmpty()) {
        Toast.makeText(context, it.error, Toast.LENGTH_LONG).show()
    } else if (it.success.isNotEmpty()) {
        val productsList = it.success as ArrayList<Any>
        val products = viewModel.getProductsList(productsList)
        // 清空旧数据,添加新产品,通知Adapter更新
        productList.clear()
        productList.addAll(products)
        productAdapter.notifyDataSetChanged()
    }
}

场景2:同一个列表展示两类数据(多类型Adapter)

先定义区分数据类型的密封类:

sealed class ListItem {
    data class CategoryItem(val category: Category) : ListItem()
    data class ProductItem(val product: Product) : ListItem()
}

再修改数据监听和Adapter逻辑:

// 统一的多类型数据源
private val combinedList = mutableListOf<ListItem>()
private val multiTypeAdapter = MultiTypeAdapter(combinedList)

// 监听分类数据
viewModel.getCategories().observe(viewLifecycleOwner) {
    if (it.error.isNotEmpty()) {
        Toast.makeText(context, it.error, Toast.LENGTH_LONG).show()
    } else if (it.success.isNotEmpty()) {
        val categoriesList = it.success as ArrayList<Any>
        val categories = viewModel.getCategoriesList(categoriesList)
        // 移除原有分类数据,添加新分类
        combinedList.removeAll { item -> item is ListItem.CategoryItem }
        combinedList.addAll(categories.map { ListItem.CategoryItem(it) })
        multiTypeAdapter.notifyDataSetChanged()
    }
}

// 监听产品数据
viewModel.getProducts(1).observe(viewLifecycleOwner) {
    if (it.error.isNotEmpty()) {
        Toast.makeText(context, it.error, Toast.LENGTH_LONG).show()
    } else if (it.success.isNotEmpty()) {
        val productsList = it.success as ArrayList<Any>
        val products = viewModel.getProductsList(productsList)
        // 移除原有产品数据,添加新产品
        combinedList.removeAll { item -> item is ListItem.ProductItem }
        combinedList.addAll(products.map { ListItem.ProductItem(it) })
        multiTypeAdapter.notifyDataSetChanged()
    }
}

3. 额外检查点

务必检查你原本的addCategories()和addProducts()方法:如果这两个方法都是往同一个全局列表里调用addAll(),那就是直接导致数据混同的原因,必须改成操作各自的独立列表,或者用上述多类型的方式处理。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:20:29