android - 删除项目并添加新项目后出现错误 : Maximum number of items supported by BottomNavigationView is 5,

标签 android kotlin bottomnavigationview android-architecture-navigation android-navigation

目前,我需要在用户注销或登录时动态更改我的 bottomnavigation#menu。这样,bottomnavigation#menu 就是 R.menu.user_logged_inR.menu.user_logged_out。我的第一个方法是这样的:

private fun setUpBottomNav(newMenu: Int) {
    with(binding.bottomNavigationView) {
        menu.clear()
        inflateMenu(newMenu)
        setupWithNavController(findNavController(R.id.fragment_container))
        // fix blinking when re selecting bottom nav item
        setOnItemReselectedListener {}
    }
}

这种方法的主要问题是,当重新创建 Activity 时(例如,当进程被终止时或者当您通过 Intent 从应用程序中打开 Web 浏览器,然后单击后退按钮时),菜单将被清除并通过 menu#clearinflateMenu 再次膨胀,导致当前底部导航状态丢失(例如,当选择配置文件选项卡并且menu#clearactivity#oncreate 中被调用,选定状态将丢失,并且主页选项卡将被选中)。

我的下一个想法是将我的R.menu_user_logged_out中的item_amount减少到四个项目,并通过检查用户是否登录或注销在运行时添加第五个菜单项。这是我的第二种方法:

// NO CLUE WHAT Menu.NONE, ..., Menu.NONE means!!!!
private fun inflateFifthMenuItem() {
   if(user.isLoggedIn) {
       binding.bottomNavigationView.menu.add(Menu.NONE, R.id.userLoggedInFragment, Menu.NONE, "Profil").setIcon(R.drawable.child_selector_profil)
   } else {
       binding.bottomNavigationView.menu.add(Menu.NONE, R.id.userLoggedOutFragment, Menu.NONE, "Profil").setIcon(R.drawable.child_selector_profil)
   }
}

现在,尽管上述解决方案听起来合乎逻辑,但 Android 有另一种观点:

   java.lang.IllegalArgumentException: Maximum number of items supported by BottomNavigationView is 5. Limit can be checked with BottomNavigationView#getMaxItemCount()
        at com.google.android.material.navigation.NavigationBarMenu.addInternal(NavigationBarMenu.java:67)
        at androidx.appcompat.view.menu.MenuBuilder.add(MenuBuilder.java:476)
        at com.example.app.presentation.main.MainActivity.signInUserBottomNav(MainActivity.kt:94)
        at com.example.app.presentation.main.MainActivity.observeLoginState$lambda-2(MainActivity.kt:75)
        at com.example.app.presentation.main.MainActivity.$r8$lambda$-vuA_npkMdEgJfGZeCrh_HfU3LQ(Unknown Source:0)
        at com.example.app.presentation.main.MainActivity$$ExternalSyntheticLambda0.onChanged(Unknown Source:4)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at androidx.lifecycle.LiveDataScopeImpl$emit$2.invokeSuspend(CoroutineLiveData.kt:99)
        at androidx.lifecycle.LiveDataScopeImpl$emit$2.invoke(Unknown Source:10)
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:165)
        at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
        at androidx.lifecycle.LiveDataScopeImpl.emit(CoroutineLiveData.kt:97)
        at com.example.app.presentation.main.ActivityViewModel$loginState$1.invokeSuspend(ActivityViewModel.kt:26)
        at com.example.app.presentation.main.ActivityViewModel$loginState$1.invoke(Unknown Source:8)
        at com.example.app.presentation.main.ActivityViewModel$loginState$1.invoke(Unknown Source:4)
        at androidx.lifecycle.BlockRunner$maybeRun$1.invokeSuspend(CoroutineLiveData.kt:176)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:367)
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.startCoroutineImpl(Builders.common.kt:192)
        at kotlinx.coroutines.BuildersKt.startCoroutineImpl(Unknown Source:1)
        at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:134)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
        at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
        at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
        at androidx.lifecycle.BlockRunner.maybeRun(CoroutineLiveData.kt:174)
        at androidx.lifecycle.CoroutineLiveData.onActive(CoroutineLiveData.kt:240)
        at androidx.lifecycle.LiveData.changeActiveCounter(LiveData.java:390)
        at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:466)
        at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:425)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
        at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:265)
        at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:307)
        at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:148)
        at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134)
        at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:68)
        at androidx.lifecycle.ReportFragment$LifecycleCallbacks.onActivityPostStarted(ReportFragment.java:187)
        at android.app.Activity.dispatchActivityPostStarted(Activity.java:1248)
        at android.app.Activity.performStart(Activity.java:7865)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

所以我的问题是:

  1. 如何根据某些条件动态添加第五个项目或
  2. 如何根据某些条件动态更改菜单(例如,当用户登录时,按配置文件按钮应将您导航到 userLoggedInFragment 而不是 userLoggedOutFragment

最佳答案

对于那些在这里绊倒的人:如果您在布局文件中使用 app:menu="@menu/my_menu" 设置菜单,并且还使用 inflateMenu( R.menu.my_menu) 在您的 Java/Kotlin 代码中。

删除其中一个,错误就会消失。

关于android - 删除项目并添加新项目后出现错误 : Maximum number of items supported by BottomNavigationView is 5,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69098834/

相关文章:

javax.net.ssl.SSLProtocolException : SSL handshake aborted: ssl=0x7fa2258640: Failure in SSL library, 通常是协议(protocol)错误

android - 无法实例化接收器 java.lang.ClassNotFoundException

android - 无法使用groundOverlay在android中的google map api v2上显示图像

generics - Kotlin 实体化类型参数不智能转换

android - RxJava 和改造的单元测试

android - 底部导航上方的 Bottom Sheet

java - 如何使用 BottomNavigationView 隐藏 TabLayout

android - 找不到处理 Intent { act=android.intent.action.CALL dat=+123456789 pkg=com.android.phone } 的 Activity

java - RxJava 并发修改异常

android - BottomNavigationView没有显示