如何防止在背面片段导航上再次设置视图模型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何防止在背面片段导航上再次设置视图模型相关的知识,希望对你有一定的参考价值。

我正在使用android Jetpack Navigation,MVVM和dataBinding,我遇到了一个问题。每当我从详细信息片段导航回来时,我的主要List片段都会刷新(再次调用API,再次绘制recyclerList)。我怎么能阻止这个?

这是Main List Fragment代码:

class PostListFragment : BaseFragment() {

private lateinit var viewModel: PostListViewModel

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    val binding = TestFragmentBinding.inflate(inflater, container, false)
    val factory = InjectorUtils.providePostListViewModelFactory()
    viewModel = ViewModelProviders.of(this, factory).get(PostListViewModel::class.java)

    val adapter = MainListAdapter()
    binding.mainList.adapter = adapter

    binding.let {
        it.viewmodel = viewModel
        it.setLifecycleOwner(this@PostListFragment)
    }

    subscribeUi(adapter)
    return binding.root
}

private fun subscribeUi(adapter: MainListAdapter) {

    viewModel.progressVisible.postValue(true)
    addToDisposable(viewModel.getContentRepository().getAllPosts(requireContext())
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe({ result ->
            viewModel.progressVisible.postValue(false)
            adapter.submitList(result)
        }, { error ->
            viewModel.progressVisible.postValue(false)
        }))
}

}

另外我要补充一点,我在MainFragment上使用这个包含viewPager的片段。

我的MainFragment的代码:

class MainFragment : Fragment() {

private lateinit var sharedViewModel: SharedNewPostViewModel
private lateinit var viewModel: MainViewModel

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    val binding = MainFragmentBinding.inflate(inflater, container, false)

    val factory = InjectorUtils.provideMainViewModelFactory()
    viewModel = ViewModelProviders.of(this, factory).get(MainViewModel::class.java)

    binding.let {
        it.viewModel = viewModel
        it.setLifecycleOwner(this@MainFragment)
    }

    sharedViewModel = activity?.run {
        ViewModelProviders.of(this).get(SharedNewPostViewModel::class.java)
    } ?: throw Exception("Invalid activity")

    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val pagerAdapter = MainPagerAdapter(childFragmentManager)

    viewPager.adapter = pagerAdapter
    tabLayout.setupWithViewPager(viewPager)
}

}

答案

需要检查savedInstanceState中的Activity.onCreate()

if(savedInstanceState == null) {
    ...
}

当它不是null时,不要给Fragment充气 - 后来不会再召唤Fragment.onCreateView()两次(否则很难从那里返回View)。

以上是关于如何防止在背面片段导航上再次设置视图模型的主要内容,如果未能解决你的问题,请参考以下文章

导航架构片段重载问题

如何保存具有列表视图的片段状态

防止导航到同一个片段

从片段中禁用导航抽屉

使用 koin 2.2.3 和 jetpack 导航在 2 个片段之间限定视图模型

使用导航控制器按下后退按钮后如何防止前一个片段显示?