【问题标题】:BottomAppBar with BottomNavigationDrawer connected to NavigationControllerBottomAppBar 与 BottomNavigationDrawer 连接到 NavigationController
【发布时间】:2021-06-23 17:06:21
【问题描述】:

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

  • 当用户使用MainFragment 时,我想在BottomAppBar 上显示导航图标(汉堡)。用户可以点击导航图标并显示BottomNavigationDrawer
  • 当用户选择某个菜单项,或单击MainFragment 上的某些内容时,他会移动到另一个片段,比如DebtDetailsFragment。然后汉堡包应该被NavigationController替换为“后退箭头”

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

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

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

此方法的文档:

工具栏还会在您位于非根目的地时显示向上按钮,在根目的地时显示抽屉图标,在它们之间自动显示动画。点击导航图标时,该方法会调用[DrawerLayout.navigateUp]。

所以问题是,当NavigationControllerBottomAppBar 连接但没有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 - 汉堡不可见。

【问题讨论】:

    标签: android kotlin android-architecture-components android-architecture-navigation


    【解决方案1】:

    BottomAppBar 不应该像 anatomy of the BottomAppBar 那样显示向上按钮 - 它应该只显示抽屉图标。如在behavior documentation 中所见,向上按钮应显示在顶部Toolbar

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

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

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

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

    【讨论】:

      【解决方案2】:

      我在我的应用程序中按照以下方式使用 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>
      

      结果会是这样的

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-08
        • 2013-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-20
        相关资源
        最近更新 更多