29

我创建了一个小应用程序,其中包含三个片段,用于通过 BottomNavigationView 进行顶级导航。如果您启动应用程序并单击底部导航上的导航按钮,您会在操作栏中看到一个向上按钮。这是活动的代码:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        setSupportActionBar(toolbar)

        val navController = navHostFragment.findNavController()
        setupActionBarWithNavController(this, navController)
        setupWithNavController(bottomNav, navController)
    }

    override fun onSupportNavigateUp(): Boolean
            = findNavController(navHostFragment).navigateUp()

}

这是结果的屏幕截图。该应用程序在主屏幕上启动,我所做的只是单击底部导航视图中的配置文件按钮。

在此处输入图像描述

我试过听 BottomNavigationView 的项目选择并使用不同的NavOptions手动导航无济于事。当用户使用 BottomNavigationView 导航时,我们可以做些什么来避免在操作栏中显示向上按钮?

4

6 回答 6

49

从 1.0.0-alpha07 开始,您可以使用它AppBarConfiguration来配置该行为。

AppBarConfiguration有一个 Builder 构造函数,因此您可以Builder使用一组特定的顶级目的地创建一个新的,由它们引用id(这id是您在导航布局上设置的那个)。

新建AppBarConfiguration

val appBarConfiguration = AppBarConfiguration
            .Builder(
                    R.id.navigationHomeFragment,
                    R.id.navigationListFragment,
                    R.id.navigationProfileFragment)
            .build()

然后,而不是setupActionBarWithNavController(this, navController)你需要打电话setupActionBarWithNavController(this, navController, appBarConfiguration)

这是处理顶部导航行为的正确方法。

于 2018-11-25T01:11:13.507 回答
10

我遇到了同样的问题,我找到了一种使用NavController.addOnNavigatedListener获取当前片段的方法,因此我在 Activity 中应用了以下逻辑,现在它适用于我

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_home)
    val navHost = supportFragmentManager
            .findFragmentById(R.id.navHostFragment) as NavHostFragment

    navHost.navController.addOnNavigatedListener { _, destination ->
        val showButton = showUpButton(destination.id)
        //Here occurs the magic
        supportActionBar?.setDisplayShowHomeEnabled(showButton)
        supportActionBar?.setDisplayHomeAsUpEnabled(showButton)
    }
}

//Check according to your convenience which fragment id
//should show or hide the "Up Button"
private fun showUpButton(id: Int): Boolean {
    return id != R.id.your_home_fragment && id != R.id.your_list_fragment 
            && id != R.id.your_profile_fragment
}

这是我的项目...

在此处输入图像描述

我不知道这是否是最好的选择,但如果有人有更好的建议,将受到欢迎

于 2018-05-18T21:07:15.953 回答
5

用这个代替setupWithNavController

navController.addOnNavigatedListener(new NavController.OnNavigatedListener() {
     @Override
     public void onNavigated(@NonNull NavController controller, @NonNull NavDestination destination) {
         toolbar.setTitle(destination.getLabel());
     }
});

或 Kotlin 中的等价物。

唯一要做的setupWithNavController就是添加一个监听器来更改工具栏标题,并创建向上按钮。如果您不想要向上按钮,只需添加一个仅更改工具栏标题的侦听器。

于 2018-09-20T18:43:00.523 回答
2

您可以将导航图标设置为空,或仅更改某些目的地的图标,例如:

1)在科特林:

navController.addOnDestinationChangedListener { _, destination, _ ->
            toolbar.title = destination.label
            toolbar.navigationIcon = null
}

2)在Java中:

hostFragment.getNavController().addOnDestinationChangedListener(new OnDestinationChangedListener() {
    public final void onDestinationChanged(@NotNull NavController controller, @NotNull NavDestination destination, @Nullable Bundle arguments) {
        toolbar.setTitle(destination.getLabel());
        toolbar.setNavigationIcon(null);
    }
});
于 2020-05-03T13:44:09.670 回答
1

如果您使用NavigationUI.setupWithNavController 签出onNavDestinationSelected

在底部导航视图menu.xml中,添加android:menuCategory="secondary"相应的MenuItem

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

  <item
    android:id="@+id/profileFragment"
    android:icon="@drawable/bottom_nav_icon_profile"
    android:menuCategory="secondary"
    android:title="@string/profile" />
于 2019-06-12T14:10:32.313 回答
0

在Java中,这对我有用:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

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

    navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    AppBarConfiguration appBarConfiguration = new AppBarConfiguration
            .Builder(navController.getGraph())
            .build();
    NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);

    navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
        toolbar.setTitle(destination.getLabel());
        toolbar.setNavigationIcon(null);
    });
于 2020-10-21T17:41:47.960 回答