导航组件,控制何时显示汉堡包或后退图标
Navigation Component, Control when to show hamburger or back icon
我有以下Activity
class MainActivity : AppCompatActivity() {
private lateinit var drawerLayout: androidx.drawerlayout.widget.DrawerLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
drawerLayout = drawer_layout
val navController = Navigation.findNavController(this, R.id.fragment_main_navHost)
setSupportActionBar(toolbar)
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
navView_main.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(drawerLayout,
Navigation.findNavController(this, R.id.fragment_main_navHost))
}
override fun onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
如您所见,它与导航图相关联,我使用的是导航抽屉。当我浏览抽屉中的项目时,我想保留汉堡包图标,并且仅当我单击片段或弹出窗口中的项目时才将其更改为 up/back 按钮,并确保系统的行为根据显示的图标反映用户的期望。可以吗
按照以下步骤操作
1.绑定你的NavigationView
with NavigationUI
NavigationUI.setupWithNavController(nav_view, hostFragment.navController)
2.绑定ActionBar
With NavController
NavigationUI.setupActionBarWithNavController(this@NavActivity, hostFragment.navController)
3.绑定ActionBar
and DrawerLayout
With NavController
NavigationUI.setupActionBarWithNavController(this@NavActivity, hostFragment.navController, drawer_layout)
4. 在您的 activity
中覆盖 onSupportNavigateUp()
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(drawer_layout, hostFragment.navController)
|| super.onSupportNavigateUp()
}
样本:
class NavActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
lateinit var hostFragment: NavHostFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_nav)
setSupportActionBar(toolbar)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
nav_view.setNavigationItemSelectedListener(this)
hostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
NavigationUI.setupWithNavController(nav_view, hostFragment.navController)
NavigationUI.setupActionBarWithNavController(this@NavActivity, hostFragment.navController)
NavigationUI.setupActionBarWithNavController(this@NavActivity, hostFragment.navController, drawer_layout)
}
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(drawer_layout, hostFragment.navController) || super.onSupportNavigateUp()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.nav, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
when (item.itemId) {
R.id.action_settings -> return true
else -> return super.onOptionsItemSelected(item)
}
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
drawer_layout.closeDrawer(GravityCompat.START)
return true
}
}
输出
主页片段:
片段二:
片段树:
因此,我认为您可以使用 NavController.OnNavigatedListener 收听将显示的片段,然后更新工具栏图标。
val navController = Navigation.findNavController(this, R.id.fragment_main_navHost)
navController.addOnNavigatedListener(contoller, destination -> {
if(destination.id == R.id.fragmentTwo){
// change the toolbar icon here
}
})
对不起,我这里没有电脑,所以我写这段代码时没有任何IDE,这样可能会出错。但请接受这个想法。
希望对您有所帮助。
要控制 AppBar 导航何时显示 up/back 需要完成以下操作
1- 创建 AppBarConfiguration 并将顶级目标和 drawerLayout 传递给它
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.dest_one,
R.id.dest_two
),
drawerLayout
)
2- 告诉 AppBar 有关配置和导航的信息。这将有助于显示标题并显示向上箭头或抽屉菜单图标
setupActionBarWithNavController(navController, appBarConfig)
3- 最后重写 onOptionsItemSelected 和 onSupportNavigateUp 以及导航组件扩展以通知 AppBar 如何表现
override fun onOptionsItemSelected(item: MenuItem)= item.onNavDestinationSelected(findNavController(R.id.my_nav_host_fragment))
|| super.onOptionsItemSelected(item)
override fun onSupportNavigateUp() = findNavController(R.id.my_nav_host_fragment).navigateUp(appBarConfiguration)
参考 Google 代码实验室导航 Navigation Codelab
我有以下Activity
class MainActivity : AppCompatActivity() {
private lateinit var drawerLayout: androidx.drawerlayout.widget.DrawerLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
drawerLayout = drawer_layout
val navController = Navigation.findNavController(this, R.id.fragment_main_navHost)
setSupportActionBar(toolbar)
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
navView_main.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(drawerLayout,
Navigation.findNavController(this, R.id.fragment_main_navHost))
}
override fun onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
如您所见,它与导航图相关联,我使用的是导航抽屉。当我浏览抽屉中的项目时,我想保留汉堡包图标,并且仅当我单击片段或弹出窗口中的项目时才将其更改为 up/back 按钮,并确保系统的行为根据显示的图标反映用户的期望。可以吗
按照以下步骤操作
1.绑定你的NavigationView
with NavigationUI
NavigationUI.setupWithNavController(nav_view, hostFragment.navController)
2.绑定ActionBar
With NavController
NavigationUI.setupActionBarWithNavController(this@NavActivity, hostFragment.navController)
3.绑定ActionBar
and DrawerLayout
With NavController
NavigationUI.setupActionBarWithNavController(this@NavActivity, hostFragment.navController, drawer_layout)
4. 在您的 activity
中覆盖onSupportNavigateUp()
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(drawer_layout, hostFragment.navController)
|| super.onSupportNavigateUp()
}
样本:
class NavActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
lateinit var hostFragment: NavHostFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_nav)
setSupportActionBar(toolbar)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
nav_view.setNavigationItemSelectedListener(this)
hostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
NavigationUI.setupWithNavController(nav_view, hostFragment.navController)
NavigationUI.setupActionBarWithNavController(this@NavActivity, hostFragment.navController)
NavigationUI.setupActionBarWithNavController(this@NavActivity, hostFragment.navController, drawer_layout)
}
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(drawer_layout, hostFragment.navController) || super.onSupportNavigateUp()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.nav, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
when (item.itemId) {
R.id.action_settings -> return true
else -> return super.onOptionsItemSelected(item)
}
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
drawer_layout.closeDrawer(GravityCompat.START)
return true
}
}
输出
主页片段:
片段二:
片段树:
因此,我认为您可以使用 NavController.OnNavigatedListener 收听将显示的片段,然后更新工具栏图标。
val navController = Navigation.findNavController(this, R.id.fragment_main_navHost)
navController.addOnNavigatedListener(contoller, destination -> {
if(destination.id == R.id.fragmentTwo){
// change the toolbar icon here
}
})
对不起,我这里没有电脑,所以我写这段代码时没有任何IDE,这样可能会出错。但请接受这个想法。
希望对您有所帮助。
要控制 AppBar 导航何时显示 up/back 需要完成以下操作
1- 创建 AppBarConfiguration 并将顶级目标和 drawerLayout 传递给它
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.dest_one,
R.id.dest_two
),
drawerLayout
)
2- 告诉 AppBar 有关配置和导航的信息。这将有助于显示标题并显示向上箭头或抽屉菜单图标
setupActionBarWithNavController(navController, appBarConfig)
3- 最后重写 onOptionsItemSelected 和 onSupportNavigateUp 以及导航组件扩展以通知 AppBar 如何表现
override fun onOptionsItemSelected(item: MenuItem)= item.onNavDestinationSelected(findNavController(R.id.my_nav_host_fragment))
|| super.onOptionsItemSelected(item)
override fun onSupportNavigateUp() = findNavController(R.id.my_nav_host_fragment).navigateUp(appBarConfiguration)
参考 Google 代码实验室导航 Navigation Codelab