导航组件:如何在每个片段中设置带工具栏的抽屉

Navigation Component: How to set drawer with toolbar in each fragment

我正在使用导航组件并希望在每个片段中将抽屉布局与工具栏连接起来,而不是 activity。

我尝试了在 onViewCreated() 上调用的这个 ,但是从 activity 引用的任何视图都是空的。我想这是因为片段在从 activity 的 onCreate 方法返回之前在布局中膨胀了。

我使用此扩展功能将抽屉与片段的工具栏连接起来,我尝试从 onCreateView() 和 onViewCreated() 调用它但没有成功,activity 的抽屉布局始终无效的。我只有在从 onStart() 调用时才工作,但我认为这不是正确的方法:

private fun AppCompatActivity.setToolbar() {
    setSupportActionBar(binding.toolbar)
    setHasOptionsMenu(true)
    val drawer = findViewById<DrawerLayout>(R.id.drawer)
    binding.toolbar.setupWithNavController(findNavController(), drawer)
}

调用此函数的正确位置是什么?

当您调用 setContentView(R.id.activity_layout) 时,整个视图层次结构首先膨胀,然后附加到 Activity。只有在 setContentView() returns 之后 findViewById() 才会找到任何新膨胀的视图。

当您使用 <fragment> 标记时,片段的视图及其所有子片段的视图将作为该 inflation 调用的一部分同步创建。这意味着在调用 onCreateView()onViewCreated() 方法时 setContentView() 尚未完成。这就是为什么调用 findViewById() returns null - activity 的视图实际上还没有完成创建。

FragmentContainerView 是专门为避免这些特殊情况而构建的,而是使用与其他片段相同的机制 - 即,它只是使用正常的 FragmentTransaction 来添加你的片段 - 就像你一样自己在 onCreate() 方法中调用 beginTransaction()+commitNow()。这意味着 Fragment 不会被迫同步创建其视图作为 setContentView() 的一部分,而是可以与其他 Fragment after setContentView() [=39= 一起创建].这就是允许 onCreateView()onViewCreated() 中的 findViewById() 工作的原因。