Kotlin RecyclerView垂直列表返回后数据重复累加问题求助
问题分析与解决方案
问题原因
垂直RecyclerView数据重复累加的核心原因是:HomeFragment中用于分类存储数据的全局列表(newStateList、popularList、recomendedList)未在每次请求数据前清空。每次切换回首页时,onActivityCreated会重新调用presenter.getHome()拉取数据,而onHomeSuccess方法直接往已有数据的列表中追加新数据,导致新旧数据叠加。
水平RecyclerView无此问题,是因为它每次都直接用接口返回的完整homeResponse.data创建全新的HomeAdapter,数据源不会复用旧列表。
修复方案
只需在onHomeSuccess处理数据前,先清空三个分类列表,确保每次基于新接口数据重新填充。
修改HomeFragment的onHomeSuccess方法
在遍历接口数据前添加清空逻辑:
override fun onHomeSuccess(homeResponse: HomeResponse) { // 清空旧数据,避免重复累加 newStateList?.clear() popularList?.clear() recomendedList?.clear() for (a in homeResponse.data.indices) { var items: List<String> = homeResponse.data[a].types?.split(",") ?: ArrayList() for (x in items.indices) { if (items[x].equals("new_craft", true)) { newStateList?.add(homeResponse.data[a]) } else if (items[x].equals("recommended", true)) { recomendedList?.add(homeResponse.data[a]) } else if (items[x].equals("popular", true)) { popularList?.add(homeResponse.data[a]) } } } // 后续代码保持不变 adapter = HomeAdapter(homeResponse.data, this) val layoutManager: RecyclerView.LayoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) rvList.layoutManager = layoutManager rvList.adapter = adapter val sectionsPagerAdapter = SectionsPagerAdapter( childFragmentManager ) sectionsPagerAdapter.setData(newStateList, popularList, recomendedList) viewPager.adapter = sectionsPagerAdapter tabLayout.setupWithViewPager(viewPager) }
额外优化建议
- 彻底避免全局列表复用风险:将分类列表改为
onHomeSuccess内部的局部变量,每次请求都生成新列表,彻底杜绝旧数据残留:
override fun onHomeSuccess(homeResponse: HomeResponse) { // 每次请求创建新列表,替代全局变量 val newStateList = arrayListOf<Data>() val popularList = arrayListOf<Data>() val recomendedList = arrayListOf<Data>() for (a in homeResponse.data.indices) { var items: List<String> = homeResponse.data[a].types?.split(",") ?: ArrayList() for (x in items.indices) { if (items[x].equals("new_craft", true)) { newStateList.add(homeResponse.data[a]) } else if (items[x].equals("recommended", true)) { recomendedList.add(homeResponse.data[a]) } else if (items[x].equals("popular", true)) { popularList.add(homeResponse.data[a]) } } } // 后续代码使用局部列表 adapter = HomeAdapter(homeResponse.data, this) val layoutManager: RecyclerView.LayoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) rvList.layoutManager = layoutManager rvList.adapter = adapter val sectionsPagerAdapter = SectionsPagerAdapter( childFragmentManager ) sectionsPagerAdapter.setData(newStateList, popularList, recomendedList) viewPager.adapter = sectionsPagerAdapter tabLayout.setupWithViewPager(viewPager) }
修改后可删除HomeFragment中定义的三个全局列表变量,进一步降低出错概率。
- Fragment生命周期优化:若底部导航切换时Fragment会重建,建议在
onCreate或onViewCreated中初始化Presenter,避免onActivityCreated重复调用导致多次请求数据(若Presenter未做请求防抖)。
内容的提问来源于stack exchange,提问作者Alfian Yuda Pratama
相关产品推荐
相关产品推荐

