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

时间:2020-10-05 18:44:44

标签: android navigation-drawer android-architecture-navigation android-navigation android-navigation-graph

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

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

我使用此扩展功能将抽屉与片段的工具栏连接起来,我尝试从onCreateView()和onViewCreated()调用它,但是没有用,并且活动的抽屉布局始终为null。我只能通过onStart()调用它,但是我认为这不是正确的方法:

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

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

1 个答案:

答案 0 :(得分:2)

调用setContentView(R.id.activity_layout)时,首先放大整个视图层次结构,然后将其附加到活动。只有在setContentView()返回之后,findViewById()才能找到任何新近膨胀的视图。

当您使用<fragment>标签时,Fragment的视图及其所有子片段的视图将作为该通胀调用的一部分同步创建。这意味着在调用setContentView()onCreateView()方法时onViewCreated()尚未完成。这就是为什么调用findViewById()返回null的原因-活动的视图实际上尚未完成创建。

FragmentContainerView是专门为避免这些特殊情况而构建的,而是使用与其他片段相同的机制-即,它仅使用普通的FragmentTransaction添加片段-就像您调用{您自己的beginTransaction()方法中的{1}} + commitNow()。这意味着Fragment不会被迫作为onCreate()的一部分同步创建其视图,而是可以在 setContentView()返回之后与所有其他Fragment一起创建。这就是setContentView()findViewById()中的onCreateView()的作用。