我正在使用导航组件,并且希望在每个片段而不是活动中将抽屉布局与工具栏连接起来。
我尝试了这个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)
}
调用此函数的正确位置是什么?
答案 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()
的作用。