BottomAppBar 与 BottomNavigationDrawer 连接到 NavigationController
BottomAppBar with BottomNavigationDrawer connected to NavigationController
您好,我正在尝试在我的项目中使用新的 arch 组件。简短描述我想要实现的目标:
- 当用户打开时
MainFragment
我想在 BottomAppBar 上显示导航图标(汉堡包)。用户可以单击导航图标并显示 BottomNavigationDrawer
- 当用户 select 某个菜单项,或在
MainFragment
上单击某些内容时,他将移动到另一个片段,比如说 DebtDetailsFragment
。然后Hamburger应该用'Back arrow'替换成NavigationController
下面我粘贴了我的 MainActivity
代码。当我用导航控制器评论行时,汉堡包图标可见并且 BottomNavigationDrawer
能够显示。
但是当我取消注释这一行时,汉堡包消失了,因为 NavigationController
对 BottomNavigationDrawer
中使用的 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>
结果会是这样
您好,我正在尝试在我的项目中使用新的 arch 组件。简短描述我想要实现的目标:
- 当用户打开时
MainFragment
我想在 BottomAppBar 上显示导航图标(汉堡包)。用户可以单击导航图标并显示BottomNavigationDrawer
- 当用户 select 某个菜单项,或在
MainFragment
上单击某些内容时,他将移动到另一个片段,比如说DebtDetailsFragment
。然后Hamburger应该用'Back arrow'替换成NavigationController
下面我粘贴了我的 MainActivity
代码。当我用导航控制器评论行时,汉堡包图标可见并且 BottomNavigationDrawer
能够显示。
但是当我取消注释这一行时,汉堡包消失了,因为 NavigationController
对 BottomNavigationDrawer
中使用的 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>
结果会是这样