首页 > 解决方案 > 避免使用导航组件按返回箭头重新创建片段

问题描述

我在 SO 上看到了类似的问题,但我找不到答案。

如果我从服务器接收数据(电影列表)并将其显示在屏幕上,然后向下滚动并单击某些电影以观看信息,然后按返回箭头并再次更新列表,即片段被重新创建并向新的服务器发出请求。我怎样才能避免它,以便当我按下后退箭头时,我会继续从我停止的元素向下滚动。我使用 Navigation 组件,我使用 MVVM 模式,我使用 Paging V3 库。

这是我的视图模型

@HiltViewModel
class HomeViewModel @Inject constructor(
    private val moviePagingSource: MoviePagingSource
) : ViewModel() {

     fun fetchPopularMoviesWithDetails(): Flow<PagingData<PopularMovieWithDetailsModel>>{

             return Pager(config = PagingConfig(
                 pageSize = 20,
                 enablePlaceholders = false
             ),
                 pagingSourceFactory = { moviePagingSource }
             ).flow
         }

}

这是我从 ViewModel 调用数据的 MovieListFragmetn 方法

 private fun setupMoviesList() {

        lifecycleScope.launch {
            viewModel.fetchPopularMoviesWithDetails().collectLatest {
                moviesAdapter.submitData(it)
            }
        }
    }

这是我导航到 DetailsMovieFragmetn 的 MovieListFragmetn 方法

  private fun openMovieDetailsScreen() {
        moviesAdapter.onClickItem(object : MovieAdapter.OnclickMovieItemListener {
            override fun getMovieModel(movieWithDetailsModel: PopularMovieWithDetailsModel) {
                val bundle = Bundle()
                bundle.putKSerializable("movieObject", movieWithDetailsModel)
                findNavController().navigate(
                    R.id.action_homeFragment_to_movieDetailsFragment,
                    bundle
                )
            }

        })
    }

标签: androidandroid-fragments

解决方案


我在@ianhanniballake 的帮助下更改了我的 ViewModel,它现在可以正常工作

@HiltViewModel
class HomeViewModel @Inject constructor(
    private val moviePagingSource: MoviePagingSource
) : ViewModel() {

    private var lastFetchedMovieResult: Flow<PagingData<PopularMovieWithDetailsModel>>? = null

    fun fetchPopularMoviesWithDetails(): Flow<PagingData<PopularMovieWithDetailsModel>> {

        val lastMovieResult = lastFetchedMovieResult
        if (lastMovieResult != null) return lastMovieResult

        val newFetchedMovieResult = Pager(config = PagingConfig(
            pageSize = 20,
            enablePlaceholders = false
        ),
            pagingSourceFactory = { moviePagingSource }
        ).flow.cachedIn(viewModelScope)

        lastFetchedMovieResult = newFetchedMovieResult

        return newFetchedMovieResult
    }

}

推荐阅读