导航组件替换/更改后台堆栈

Posted

技术标签:

【中文标题】导航组件替换/更改后台堆栈【英文标题】:Navigation Component replace/ change backstacks 【发布时间】:2021-09-30 09:48:03 【问题描述】:

我有带有导航控制器的导航抽屉设置的底部导航。我目前正在使用最新的 v2.4.0-alpha05,它分别管理每个底部导航选项卡的 backstacks。问题是,我有一个自定义导航抽屉(带有一堆文本视图的线性布局),它归活动本身而不是片段所有。此抽屉内有一个配置文件选项,我想在单击它时导航到帐户片段。好吧,我可以用navController.navigate(R.id.action_global_accountFragment) 做到这一点,但是这个片段现在将被添加到主片段的后台堆栈之上。 每当我切换回我的主片段(通过底部导航)时,我只想要主片段的后台而不是帐户片段,即我希望它要么从堆栈中删除,要么以任何方式切换到后台堆栈到帐户片段,只要我点击配置文件视图.有什么办法可以做这些事情或任何其他解决方案吗?我也附上了我的主要活动 oncreate 和 navcontroller 的 onDestinationChanged 方法。任何帮助表示赞赏。

 NavHostFragment navHostFragment =
            (NavHostFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.nav_host_fragment_activity_main);
    navController = navHostFragment.getNavController();

    setSupportActionBar(toolbar);


    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
            R.id.homeFragment, R.id.listingsFragment, R.id.featuredFragment, R.id.categoriesFragment
            , R.id.accountFragment)
            .setOpenableLayout(drawerLayout)
            .build();


    Objects.requireNonNull(getSupportActionBar()).setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_nav_menu_icon);



     NavigationUI.setupWithNavController(toolbar,navController,appBarConfiguration);
     NavigationUI.setupWithNavController(navViewBottom,navController);


    navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() 
        @Override
        public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) 
            if (destination.getId() == R.id.homeFragment)
                    controller.popBackStack(R.id.homeFragment,false, true);    //popping these so that if account fragment is in stack, it will get popped as well, but that also pops all other fragments
                Objects.requireNonNull(getSupportActionBar()).show();
               Objects.requireNonNull(getSupportActionBar()).setHomeAsUpIndicator(R.drawable.ic_nav_menu_icon);
            

            if (destination.getId() == R.id.categoriesFragment)
                
                controller.popBackStack(R.id.categoriesFragment,false);
                Objects.requireNonNull(getSupportActionBar()).show();
                Objects.requireNonNull(getSupportActionBar()).setHomeAsUpIndicator(R.drawable.ic_nav_menu_icon);
            

            if (destination.getId() == R.id.listingsFragment)
                controller.popBackStack(R.id.listingsFragment,false);
                Objects.requireNonNull(getSupportActionBar()).show();
                Objects.requireNonNull(getSupportActionBar()).setHomeAsUpIndicator(R.drawable.ic_nav_menu_icon);
            

            if (destination.getId() == R.id.featuredFragment) 
                controller.popBackStack(R.id.featuredFragment,false);
                Objects.requireNonNull(getSupportActionBar()).show();
                Objects.requireNonNull(getSupportActionBar()).setHomeAsUpIndicator(R.drawable.ic_nav_menu_icon);
            
            if (destination.getId() == R.id.accountFragment)
                controller.popBackStack(R.id.accountFragment,false);
                Objects.requireNonNull(getSupportActionBar()).hide();
            
            
        
    );

这是我想要导航到帐户片段的布局的 onclick

    @Override
public void onClick(View view) 
    
    if (view.getId() == R.id.relativeLayout_profile_navDrawer) 
        drawerLayout.closeDrawer(GravityCompat.START);
        navController.navigate(R.id.action_global_account);

    

【问题讨论】:

【参考方案1】:

我刚刚设置了bottomNavView.setSelectedItemId(R.id.yourwantedfargment),它为我完成了这项工作!

【讨论】:

以上是关于导航组件替换/更改后台堆栈的主要内容,如果未能解决你的问题,请参考以下文章

如何找出前一个片段正在使用导航组件

使用 React Navigation 导航堆栈时重新渲染组件

将 prop 从组件传递到堆栈导航器

导航架构组件 singleTask 或 singleInstance 在返回堆栈中

如何在颤动中推动替换删除整个导航堆栈?

使用导航架构组件添加(而不是替换)片段