如何使用Architecture组件导航控制器添加(而不是替换)片段

moh*_*ter 30 android android-architecture-components android-architecture-navigation

我有一个产品列表片段和许多其他片段的活动,我正在尝试使用架构组件导航控制器.

问题是:它取代了(起始目的地)产品列表片段,我不希望在用户单击后退按钮时重新加载列表.

如何使片段事务成为添加而不是替换.

utk*_*tlu 11

Android 导航组件只是替换,但您想添加片段而不是像对话框那样替换,您可以使用它,但需要最小化。导航组件的“版本 2.1.0 ”。

解决方案

你可以看到“对话目的地


Rai*_*ker 5

我遇到了同样的问题,在等待add片段事务的其他选项时,我实施了这项工作以在回击时保留状态。

我只是添加了一个检查是否存在绑定然后我只是恢复以前的状态,与网络调用相同,我添加了一个检查数据是否存在于视图模型中然后不进行网络重新获取。经过测试,它按预期工作。

编辑:对于回收器视图,我相信它会自动返回到列表在您从片段导航之前的状态,但onSavedInstanceSate也可以将位置存储在

  private lateinit var binding: FragmentSearchResultsBinding

  override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        viewModel =
            ViewModelProviders.of(this, mViewModelFactory).get(SearchResultsViewModel::class.java)
        return if (::binding.isInitialized) {
            binding.root
        } else {
            binding = DataBindingUtil.inflate(inflater, R.layout.fragment_search_results, container, false)

            with(binding) {
               //some stuff
                root
            }
        }
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //reload only if search results are empty
        if (viewModel.searchResults.isEmpty()) {
           args.searchKey.let {
                binding.toolbarHome.title = it
                viewModel.onSearchResultRequest(it)
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

您必须覆盖 NavHostFragment 的createFragmentNavigator方法并返回YourFragmentNavigator.

YourFragmentNavigator必须覆盖 FragmentNavigator 的navigate方法。

将 FragmentNavigator 的navigate方法复制并粘贴到您的YourFragmentNavigator.

在导航方法,改变线ft.replace(mContainerId, frag);

if (fragmentManager.fragments.size <= 0) {
    ft.replace(containerId, frag)
} else {
    ft.hide(fragmentManager.fragments[fragmentManager.fragments.size - 1])
    ft.add(containerId, frag)
}
Run Code Online (Sandbox Code Playgroud)

解决方案将如下所示:

class YourNavHostFragment : NavHostFragment() {
override fun createFragmentNavigator(): Navigator<...> {
    return YourFragmentNavigator(...)
}}
Run Code Online (Sandbox Code Playgroud)

....

class YourFragmentNavigator(...) : FragmentNavigator(...) {

override fun navigate(...){
    ....
    if (fragmentManager.fragments.size <= 0) {
        ft.replace(containerId, frag)
    } else {
        ft.hide(fragmentManager.fragments[fragmentManager.fragments.size - 1])
        ft.add(containerId, frag)
     }
     ....
}}
Run Code Online (Sandbox Code Playgroud)

在您的 xml 中使用YourNavHostFragment.


小智 -1

查了一下,不太可能,但是问题本身可以用viewmodel和livedata或者rxjava来解决。因此,片段状态在交易后保留,我的产品列表不会每次都重新加载

  • 一个代码示例或一些链接来支持你的答案会很好。 (4认同)
  • 据我所知 viewmodel 不会有帮助。片段被破坏,结果,它实际上创建了一个全新的视图模型。我自己也有同样的问题。我当前的解决方法是在活动范围内使用状态对象作为视图模型。 (4认同)