BottomAppBar 与 BottomNavigationDrawer 连接到 NavigationController

BottomAppBar with BottomNavigationDrawer connected to NavigationController

您好,我正在尝试在我的项目中使用新的 arch 组件。简短描述我想要实现的目标:

下面我粘贴了我的 MainActivity 代码。当我用导航控制器评论行时,汉堡包图标可见并且 BottomNavigationDrawer 能够显示。

但是当我取消注释这一行时,汉堡包消失了,因为 NavigationControllerBottomNavigationDrawer 中使用的 NavigationView 一无所知。我不使用 DrawerLayout,所以控制器认为不需要汉堡包。

方法setupWithNavController可以控制汉堡图标和后退箭头,但我必须提供DrawerLayout作为我不使用的参数。

此方法的文档:

The Toolbar will also display the Up button when you are on a non-root destination and the drawer icon when on the root destination, automatically animating between them. This method will call [DrawerLayout.navigateUp] when the navigation icon is clicked.

那么问题来了,NavigationController连接BottomAppBar但没有连接DrawerLayout时,如何显示汉堡图标?我将在 onOptionsItemSelected 方法中自己处理汉堡包点击。


class MainActivity : BaseActivity() {

    @Inject
    lateinit var viewModelProvider: ViewModelProvider.Factory

    private val viewModel: MainActivityViewModel by lazy {
        ViewModelProviders.of(this, viewModelProvider).get(MainActivityViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(bottomAppBar)
        val navController = findNavController(R.id.main_nav_host_fragment)
        //bottomAppBar.setupWithNavController(navController)
        
        onDestroyDisposables += viewModel.uiStateObservable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(::render, Timber::e)
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.bottomappbar_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when (item?.itemId) {
            android.R.id.home -> {
                val bottomNavDrawerFragment = BottomNavigationDrawerFragment()
                bottomNavDrawerFragment.show(supportFragmentManager, bottomNavDrawerFragment.tag)
            }
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onSupportNavigateUp(): Boolean {
        return findNavController(R.id.main_nav_host_fragment).navigateUp()
    }
}

没有设置导航控制器:

底部导航抽屉

设置了 NavigationController - 汉堡不可见。

BottomAppBar 不应像 anatomy of the BottomAppBar - it should only ever display the drawer icon. As seen in the behavior documentation 那样显示向上按钮,向上按钮应显示在顶部 Toolbar

因此,您永远不应该调用 bottomAppBar.setupWithNavController(navController),而是使用您拥有的任何顶部 Toolbar 来调用 setupWithNavController(navController)

要设置您的 BottomAppBar,您应该设置自己的抽屉图标并 handle clicks on the drawer icon 自己。

DrawerArrowDrawable class 可以为您提供正确的抽屉图标:

val icon = DrawerArrowDrawable(bottomAppBar.context)
bottomAppBar.navigationIcon = icon

我在我的应用程序中按以下方式实现了带有 Jetpack 导航抽屉组件的 BottomAppBar。

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        BottomAppBar bottomAppBar = findViewById(R.id.bottomAppBar);
        setSupportActionBar(bottomAppBar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        NavigationView navigationView = findViewById(R.id.nav_view);
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        return NavigationUI.navigateUp(navController, drawer)
                || super.onSupportNavigateUp();
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <include layout="@layout/content_main" />

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottomAppBar"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:layout_gravity="bottom"
        app:fabCradleVerticalOffset="16dp"
        app:navigationIcon="@drawable/ic_baseline_menu_24"
        app:navigationContentDescription="@string/nav_header_desc"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        style="@style/Widget.MaterialComponents.BottomAppBar.Colored"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_menu_send"
        app:layout_anchor="@id/bottomAppBar"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

结果会是这样