导航组件:如何在每个片段中设置带有工具栏的抽屉
我正在使用导航组件,并希望将抽屉布局与每个片段中的工具栏(而不是活动)连接起来。
我尝试了这个在 onViewCreated() 上调用的 answer ,但从活动引用的任何视图都是空的。我猜这是因为在从活动的 onCreate 方法返回之前片段在布局中膨胀了。
我使用此扩展函数将抽屉与片段的工具栏连接,我尝试从 onCreateView() 和 onViewCreated() 调用它,但没有工作,并且活动的抽屉布局始终为空。仅当从 onStart() 调用它时我才有效,但我认为这不是正确的方法:
private fun AppCompatActivity.setToolbar() {
setSupportActionBar(binding.toolbar)
setHasOptionsMenu(true)
val drawer = findViewById<DrawerLayout>(R.id.drawer)
binding.toolbar.setupWithNavController(findNavController(), drawer)
}
调用此函数的正确位置是什么?
I'm using navigation component and want to connect drawer layout with toolbar in each fragment, not the activity.
I tried this answer which is called on onViewCreated() but any view referenced from the activity is null. I guess it's because fragment is inflated in the layout before returning from the activity's onCreate method.
I use this extension function to connect the drawer with the fragment's toolbar, I tried to call it from onCreateView() and onViewCreated() but did't work and the activity's drawer layout is always null. I works only if it's called from onStart() but I don't think it's the right way:
private fun AppCompatActivity.setToolbar() {
setSupportActionBar(binding.toolbar)
setHasOptionsMenu(true)
val drawer = findViewById<DrawerLayout>(R.id.drawer)
binding.toolbar.setupWithNavController(findNavController(), drawer)
}
What's the right place to call this function?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您调用
setContentView(R.id.activity_layout)
时,整个视图层次结构首先会膨胀,然后附加到 Activity。只有在setContentView()
返回后,findViewById()
才会找到任何新扩展的视图。当您使用
标记时,Fragment 的视图及其所有子 Fragment 的视图将作为该膨胀调用的一部分同步创建。这意味着在调用onCreateView()
和onViewCreated()
方法时,setContentView()
尚未完成。这就是为什么调用findViewById()
返回 null - 活动的视图实际上尚未完成创建。FragmentContainerView
是专门为避免这些特殊情况而构建的,而是使用与其他片段相同的机制 - 即,它只使用普通的FragmentTransaction
来添加您的 Fragment - 就像如果您自己在onCreate()
方法中调用了beginTransaction()
+commitNow()
。这意味着 Fragment 不会被强制同步创建其视图作为setContentView()
的一部分,而是可以与所有其他 Fragment aftersetContentView()< /code> 返回。这就是允许
onCreateView()
或onViewCreated()
中的findViewById()
工作的原因。When you call
setContentView(R.id.activity_layout)
, the entire view hierarchy is first inflated, then attached to the Activity. It is only aftersetContentView()
returns thatfindViewById()
will find any of the newly inflated views.When you use the
<fragment>
tag, the Fragment's view and the views of all of its child fragments are synchronously created as part of that inflation call. This means thatsetContentView()
has not completed by the time theonCreateView()
andonViewCreated()
methods are called. This is why that callingfindViewById()
returns null - the activity's view hasn't actually finished being created.FragmentContainerView
was specifically built to avoid these special cases and instead use the same mechanisms as other fragments - namely, it just uses a normalFragmentTransaction
to add your Fragment - the same as if you calledbeginTransaction()
+commitNow()
in youronCreate()
method yourself. This means that the Fragment is not forced to synchronously create its view as part ofsetContentView()
, but can do it alongside every other Fragment aftersetContentView()
returns. This is what allowsfindViewById()
fromonCreateView()
oronViewCreated()
work.您只需使用需要在活动中实现的接口即可实现此目的。无需从片段引用活动的抽屉布局。
界面如下:
然后在活动中:
在片段中:
You can achieve this by simply using an interface which you need to implement in activity. No need to reference activity's drawerLayout from fragment.
Interface like this:
Then in activity:
In fragment: