无法使用片段中的工具栏膨胀选项菜单
Cannot inflate option menu with toolbar in fragment
在这个应用程序中,我有 MainFragment,我尝试添加带有选项菜单的操作栏和工具栏,显示了操作栏但没有选项菜单,即使我添加了后退按钮也不起作用调用 onBackPressed
的代码
fragment_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mml.mig33.fragments.MainFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.Mig33.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.Mig33.PopupOverlay">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="@dimen/_32sdp"
android:layout_height="@dimen/_32sdp"
android:src="@drawable/ic_profile"
android:tint="@color/white" />
<TextView
android:id="@+id/userNameTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="username"
android:textColor="@color/white"
android:textSize="@dimen/_18ssp"
android:textStyle="bold">
</TextView>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.material.appbar.AppBarLayout>
</LinearLayout>
MainFragment class
class MainFragment : Fragment(R.layout.fragment_main) {
private var _binding: FragmentMainBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
setHasOptionsMenu(true)
binding.toolbar.apply {
title = ""
setNavigationIcon(R.drawable.ic_baseline_arrow_back_24)
setNavigationOnClickListener {
activity?.onBackPressedDispatcher?.onBackPressed()
}
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val viewPageAdapter = ViewPageAdapter(childFragmentManager, lifecycle)
binding.viewPager2.adapter = viewPageAdapter
val tabTitles = arrayOf("Chat", "Search", "Settings")
TabLayoutMediator(binding.tabLayout, binding.viewPager2) { tab, position ->
when (position) {
0 -> tab.text = tabTitles[0]
1 -> tab.text = tabTitles[1]
2 -> tab.text = tabTitles[2]
}
}.attach()
}
private inner class ViewPageAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount(): Int {
return 3
}
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> ChatFragment()
1 -> SearchFragment()
2 -> SettingsFragment()
else -> ChatFragment()
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_main, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_logout -> {
FirebaseAuth.getInstance().signOut()
val action = MainFragmentDirections.actionMainFragmentToLoginFragment()
findNavController().navigate(action)
return true
}
}
return false
}
}
AndroidManifest.xml 我用了 NoActionBar
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mml.mig33">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Mig33.NoActionBar">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.Mig33.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我在 Mainactivity 中测试了这段代码,它工作正常,但我需要在 MainFragment 上使用它
为什么要使用 NoActionBar
?你需要使用支持ActionBar的theme,否则你的OnCreateOptionsMenu
将不会被调用。要添加工具栏,请使用 setSupportActionBar(toolbar)
.
我通过将整个应用程序的 android:theme="@style/Theme.Mig33.NoActionBar
更改为支持操作栏的主题 android:theme="@style/Theme.Mig33"
并保留没有操作栏的 activity
来修复它
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mml.mig33">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Mig33">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.Mig33.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
在片段中调用了这个
(activity as AppCompatActivity?)!!.setSupportActionBar(binding.toolbar)
如果要使用 NoActionBar 主题,您应该在 Main Activity 中设置工具栏,或者在每个片段中定义工具栏。
看看https://developer.android.com/guide/navigation/navigation-ui#support_app_bar_variations
你必须在 OnCreateView() 中添加这个
Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.new_chat_menu);
在这个应用程序中,我有 MainFragment,我尝试添加带有选项菜单的操作栏和工具栏,显示了操作栏但没有选项菜单,即使我添加了后退按钮也不起作用调用 onBackPressed
fragment_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mml.mig33.fragments.MainFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.Mig33.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.Mig33.PopupOverlay">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="@dimen/_32sdp"
android:layout_height="@dimen/_32sdp"
android:src="@drawable/ic_profile"
android:tint="@color/white" />
<TextView
android:id="@+id/userNameTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="username"
android:textColor="@color/white"
android:textSize="@dimen/_18ssp"
android:textStyle="bold">
</TextView>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.material.appbar.AppBarLayout>
</LinearLayout>
MainFragment class
class MainFragment : Fragment(R.layout.fragment_main) {
private var _binding: FragmentMainBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
setHasOptionsMenu(true)
binding.toolbar.apply {
title = ""
setNavigationIcon(R.drawable.ic_baseline_arrow_back_24)
setNavigationOnClickListener {
activity?.onBackPressedDispatcher?.onBackPressed()
}
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val viewPageAdapter = ViewPageAdapter(childFragmentManager, lifecycle)
binding.viewPager2.adapter = viewPageAdapter
val tabTitles = arrayOf("Chat", "Search", "Settings")
TabLayoutMediator(binding.tabLayout, binding.viewPager2) { tab, position ->
when (position) {
0 -> tab.text = tabTitles[0]
1 -> tab.text = tabTitles[1]
2 -> tab.text = tabTitles[2]
}
}.attach()
}
private inner class ViewPageAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount(): Int {
return 3
}
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> ChatFragment()
1 -> SearchFragment()
2 -> SettingsFragment()
else -> ChatFragment()
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_main, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_logout -> {
FirebaseAuth.getInstance().signOut()
val action = MainFragmentDirections.actionMainFragmentToLoginFragment()
findNavController().navigate(action)
return true
}
}
return false
}
}
AndroidManifest.xml 我用了 NoActionBar
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mml.mig33">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Mig33.NoActionBar">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.Mig33.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我在 Mainactivity 中测试了这段代码,它工作正常,但我需要在 MainFragment 上使用它
为什么要使用 NoActionBar
?你需要使用支持ActionBar的theme,否则你的OnCreateOptionsMenu
将不会被调用。要添加工具栏,请使用 setSupportActionBar(toolbar)
.
我通过将整个应用程序的 android:theme="@style/Theme.Mig33.NoActionBar
更改为支持操作栏的主题 android:theme="@style/Theme.Mig33"
并保留没有操作栏的 activity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mml.mig33">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Mig33">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.Mig33.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
在片段中调用了这个
(activity as AppCompatActivity?)!!.setSupportActionBar(binding.toolbar)
如果要使用 NoActionBar 主题,您应该在 Main Activity 中设置工具栏,或者在每个片段中定义工具栏。
看看https://developer.android.com/guide/navigation/navigation-ui#support_app_bar_variations
你必须在 OnCreateView() 中添加这个
Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.new_chat_menu);