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

删除或修改条目状态后无法加载新列表的问题求助

Paging3 删除条目后无法刷新列表的解决方案

我使用Paging3库通过分页从API获取数据,在onViewCreated中能成功加载数据。但调用删除API移除列表条目后,无法将新列表加载到适配器中;重建Fragment后则能正常显示。尝试过likesAdapter?.notifyItemChanged(position)、likesAdapter?.notifyDataSetChanged()以及调用viewModel.getPaginationData()方法,均无效。如何在viewModel.stateDeleteMatch.observe方法中实现正确的刷新效果?


相关代码

LikesFragment.kt

@AndroidEntryPoint
class LikesFragment : BaseFragment<FragmentLikesBinding>(
    bindingInflater = FragmentLikesBinding::inflate
) {
    private var likesAdapter: LikesAdapter? = null

    private val viewModel: LikesFragmentViewModel by viewModels()

    override fun onCreateFinished() {
        initLikesAdapter()
        viewModel.getPaginationData()
    }

    override fun initObservers() {
        lifecycleScope.launch {
            viewModel.pagingData.collect { pagingData ->
                hideProgress()
                likesAdapter?.submitData(pagingData)
            }
        }
        viewModel.stateDeleteMatch.observe(viewLifecycleOwner) { state ->
            state?.let { result ->
                when (result.isLoading) {
                    false -> {
                        hideProgress()
                        if (result.error != "hata") {
                            result.deletePositionId?.let { position ->
                                // 需要在这里刷新适配器数据
                                viewModel.getPaginationData()
                                // likesAdapter?.notifyItemChanged(position)
                            }
                        } else {
                            InfoBottomSheetDialog(
                                customMessage = getString(R.string.can_not_delete_now)
                            ).show(childFragmentManager, InfoBottomSheetDialog.TAG)
                        }

                    }

                    true -> showProgress()
                }
            }
        }
    }
}

LikesFragmentViewModel.kt

@HiltViewModel
class LikesFragmentViewModel @Inject constructor(
    private val createUserAnswerUseCase: CreateUserAnswerUseCase,
    private val deleteMatchUseCase: DeleteMatchUseCase,
    private val likesPagingSource: LikesPagingSource
) : ViewModel() {
    var stateCreateUserAnswer = SingleLiveEvent<CreateUserAnswerState>()
        private set

    private val _pagingData = MutableStateFlow<PagingData<Likes>>(PagingData.empty())
    val pagingData: Flow<PagingData<Likes>> get() = _pagingData

    private var pageSize = 20

    private val pagingConfig = PagingConfig(
        pageSize = pageSize,
        enablePlaceholders = false
    )

    fun getPaginationData() {
        val pager = Pager(
            config = pagingConfig,
            pagingSourceFactory = { likesPagingSource }
        )

        // 观察分页数据并更新MutableStateFlow
        viewModelScope.launch {
            pager.flow.collectLatest { pagingData ->
                _pagingData.value = pagingData
            }
        }
    }
}

问题根源

  1. PagingSource复用导致缓存未更新:当前ViewModel复用了同一个LikesPagingSource实例,Paging3会缓存该数据源的加载结果,即使后端数据已删除,PagingSource未收到失效通知,不会重新请求最新数据。
  2. StateFlow未触发重新收集:_pagingData作为StateFlow,若新生成的PagingData与旧数据被判定为逻辑相等,Fragment中的collect不会触发新的submitData调用。

解决方案

方案1:触发PagingSource失效(推荐)

PagingSource默认自带invalidate()方法,调用后会清除缓存并强制重新加载数据。修改ViewModel添加刷新方法:

// LikesFragmentViewModel.kt
fun refreshAfterDelete() {
    // 让现有PagingSource失效,清除缓存
    likesPagingSource.invalidate()
    // 重新加载分页数据
    getPaginationData()
}

在Fragment的观察者中调用该方法:

// LikesFragment.kt
result.deletePositionId?.let { position ->
    viewModel.refreshAfterDelete()
}

方案2:每次创建新的PagingSource实例

调整依赖注入方式,改为注入PagingSource的工厂方法,每次加载都创建新实例,避免缓存复用:

// LikesFragmentViewModel.kt
@HiltViewModel
class LikesFragmentViewModel @Inject constructor(
    private val createUserAnswerUseCase: CreateUserAnswerUseCase,
    private val deleteMatchUseCase: DeleteMatchUseCase,
    private val likesPagingSourceFactory: () -> LikesPagingSource // 改为工厂注入
) : ViewModel() {
    // ... 其他代码不变

    fun getPaginationData() {
        val pager = Pager(
            config = pagingConfig,
            pagingSourceFactory = { likesPagingSourceFactory() } // 每次创建新实例
        )

        viewModelScope.launch {
            pager.flow.collectLatest { pagingData ->
                _pagingData.value = pagingData
            }
        }
    }
}

之后在Fragment中直接调用viewModel.getPaginationData()即可,新的PagingSource会请求最新数据。

方案3:直接调用适配器的refresh方法

如果你的LikesAdapter继承自PagingDataAdapter,可以直接调用适配器的refresh()方法,内部会自动触发PagingSource失效:

// LikesFragment.kt
result.deletePositionId?.let { position ->
    likesAdapter?.refresh()
}

内容的提问来源于stack exchange,提问作者Ahmet Yılmaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:30:24