Android - 具有多个底部导航菜单的导航组件

Posted

技术标签:

【中文标题】Android - 具有多个底部导航菜单的导航组件【英文标题】:Android - Navigation Component with multiple menus for Bottom Navigation 【发布时间】:2021-08-25 18:06:41 【问题描述】:

我有一个 android 应用 (Java),它使用导航组件来设置底部导航。该应用由单个 Activity(主)组成,其他所有内容都加载在片段中。

这个想法是启动启动画面并检查用户是否登录。如果用户已登录,则会加载主屏幕并且底部导航(之前隐藏)变为可见。

底部导航由 3 个选项卡组成。

但是,当用户登录时,它可以是两种类型的用户之一。如果他是订阅者,他将可以访问应用程序的所有部分。但是,如果用户是访问者,他将只能访问两个部分。在这种情况下,我希望有一个不同的底部导航菜单,只有 2 个选项卡可见。

如果主 Activity 中已经分配了主底部导航,如何根据用户类型替换底部导航?

这是MainActivity中的代码:

    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);


    FragmentManager supportFragmentManager = getSupportFragmentManager();
    NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();

    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(R.id.homeFragment, R.id.libraryFragment, R.id.searchFragment, R.id.myStuffFragment).build();
    NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);

    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
    NavigationUI.setupWithNavController(bottomNav, navController);


    navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() 
        @Override
        public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) 
            if (destination.getId() == R.id.splashScreenFragment || destination.getId() == R.id.welcomeFragment || destination.getId() == R.id.signInFragment) 
                toolbar.setVisibility(View.GONE);
                bottomNav.setVisibility(View.GONE);
             else if (destination.getId() == R.id.audioPlayerFragment) 
                bottomNav.setVisibility(View.GONE);
             else 
                toolbar.setVisibility(View.VISIBLE);
                bottomNav.setVisibility(View.VISIBLE);
            
        
    );

这是 SplashScreenFragment 中的代码(这是 nav_graph 中的 startDestination):

public class SplashScreenFragment extends Fragment 

private static final String TAG = "SplashScreenFragment";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 

    View v = inflater.inflate(R.layout.fragment_splash_screen, container, false);

    return v;



@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) 
    SharedPreferences getSharedData = this.getActivity().getSharedPreferences("AppTitle", Context.MODE_PRIVATE);
    Boolean loggedIn = getSharedData.getBoolean("isUserLoggedIn", false);


    new Handler().postDelayed(new Runnable() 
        @Override
        public void run() 
            if (!loggedIn) 
                Navigation.findNavController(view).navigate(R.id.action_splashScreenFragment_to_welcomeFragment);
             else 
                Navigation.findNavController(view).navigate(R.id.action_splashScreenFragment_to_homeFragment);
            
        
    , 2000);

【问题讨论】:

那么你的问题是什么?如何更改 BottomNavigationView 中可见的菜单项?这与导航无关,只是使用了Menu API。 @ianhanniballake 如果用户不是订阅者,则底部菜单将与订阅者底部菜单完全不同。那么如何根据用户类型使用导航组件和两个不同的底部菜单呢? 导航与添加到BottomNavigationView 中的菜单没有任何关系——这就是menu.xml 完全独立于导航图XML 的原因。您是否在询问如何根据用户类型为您的 BottomNavigationView 增加不同的菜单? 【参考方案1】:

默认情况下,您可以在BottomNavigationView 中拥有完整的菜单项,因此当订阅用户登录时,不需要更改菜单。

如果用户没有订阅,那么您可以使用removeItem()以编程方式从菜单中删除所需的项目

所以,在MainActivity 中添加一个条件:

if (notSubscribedUser) 
    if (bottomNav.getMenu().findItem(R.id.my_item_id) != null)
        bottomNavigationView.getMenu().removeItem(R.id.my_item_id);

对您要删除的所有菜单项 ID 执行相同操作

【讨论】:

如何从处理订阅与非订阅情况的 SplashScreenFragment 调用 MainActivity? 您可以在SplashScreenFragment 中调用requireActivity() 并将其转换为MainActivity .. 就像MainActivity activity = (MainActivity) requireActivity() 然后将上面的代码放在某个方法中,例如checkSubscription 并使用activity.checkSubscription() 调用它

以上是关于Android - 具有多个底部导航菜单的导航组件的主要内容,如果未能解决你的问题,请参考以下文章

如何保存底部导航片段的状态 - 具有单个导航图的 Android 导航组件

Android BottomNavigationView 底部导航组件使用

每个底部导航视图菜单项的单独导航图 - Android

android 底部菜单栏实现(转)

Android学习笔记---使用TabHost实现微信底部导航栏效果

如何禁用底部导航视图的菜单项?