Menu Provider无法添加菜单至Toolbar问题排查求助
我刚接触Android Studio,折腾两天都没能让Menu Provider正常工作,求帮忙排查问题,万分感谢!
当前使用主题为Theme.Material3.Light.NoActionBar,试过给Toolbar设置空菜单和不设置菜单两种情况,均无效果。也尝试让Fragment直接继承MenuProvider接口,结果依旧。
布局代码(activity.xml中Toolbar部分)
<androidx.coordinatorlayout.widget.CoordinatorLayout android:id="@+id/coordinator_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize"> <com.google.android.material.appbar.MaterialToolbar android:id="@+id/home_top_bar" style="@style/Widget.App.Toolbar.Centered" android:layout_width="match_parent" android:layout_height="match_parent" app:menu="@menu/empty_menu"/> </com.google.android.material.appbar.AppBarLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
Activity代码
class HomeActivity : AppCompatActivity() { private lateinit var binding: ActivityHomeBinding private lateinit var navController: NavController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_home) val navHostFragment = supportFragmentManager.findFragmentById(R.id.home_nav_controller) as NavHostFragment navController = navHostFragment.navController val appBarConfiguration = AppBarConfiguration(navController.graph) binding.homeTopBar.apply { setupWithNavController(navController, appBarConfiguration) } } }
Fragment代码
class HomeFragment : Fragment() { private lateinit var binding: FragmentHomeBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentHomeBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val menuHost: MenuHost = requireActivity() menuHost.addMenuProvider(object : MenuProvider { override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { menuInflater.inflate(R.menu.home_menu, menu) } override fun onMenuItemSelected(menuItem: MenuItem): Boolean { when(menuItem.itemId) { R.id.account -> { view.findNavController().navigate(R.id.action_homeFragment_to_userFragment) return true } R.id.join_game -> { view.findNavController().navigate(R.id.action_homeFragment_to_joinGameFragment) return true } else -> return false } } }, viewLifecycleOwner, Lifecycle.State.RESUMED) binding.apply { lifecycleOwner = viewLifecycleOwner //viewModel = sharedViewModel homeFragment = this@HomeFragment } } fun newGame() { view?.findNavController()?.navigate(R.id.action_homeFragment_to_newGameFragment) } }
解决思路
- 修正MenuHost获取方式:当前用
requireActivity()作为MenuHost,但结合Navigation Component时,Fragment自身就是MenuHost,应改为:val menuHost: MenuHost = this - 移除Toolbar固定菜单绑定:删除布局中MaterialToolbar的
app:menu="@menu/empty_menu"属性,避免和MenuProvider的菜单冲突。 - 调整生命周期绑定状态:将MenuProvider的生命周期从
Lifecycle.State.RESUMED改为Lifecycle.State.STARTED,确保菜单在Fragment启动阶段就被加载:menuHost.addMenuProvider(/* ... */, viewLifecycleOwner, Lifecycle.State.STARTED) - 手动关联Toolbar到ActionBar:在Activity中添加
setSupportActionBar(binding.homeTopBar),让MenuProvider的菜单自动关联到当前Toolbar。 - 检查菜单资源配置:确认
home_menu.xml中的菜单项没有设置android:visible="false"等隐藏属性,ID配置正确。
内容的提问来源于stack exchange,提问作者Teoneeee
相关产品推荐
相关产品推荐

