导航组件,控制何时显示汉堡包或返回图标
Posted
技术标签:
【中文标题】导航组件,控制何时显示汉堡包或返回图标【英文标题】:Navigation Component, Control when to show hamburger or back icon 【发布时间】:2019-02-09 19:56:14 【问题描述】:我有以下活动
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()
您可以看到它与导航图相关联,我正在使用导航抽屉。当我浏览抽屉中的项目时,我想保留汉堡图标,并且仅在单击片段或弹出窗口中的项目时将其更改为上/后退按钮,并确保系统的行为反映了什么用户期望基于显示的图标。有可能吗
【问题讨论】:
【参考方案1】:要控制AppBar导航上/后显示的时间需要做以下操作
1- 创建 AppBarConfiguration 并将***目的地和抽屉布局传递给它
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)
参考谷歌代码实验室导航Navigation Codelab
【讨论】:
我尝试了这段代码并定义了我所有的***目的地,但是当我从***目的地移动到另一个片段时,显示返回按钮,当单击工具栏的返回按钮时,抽屉将再次打开.我该如何解决这个问题 能否请您分享代码 sn-p 或其他东西,看看您在做什么 能否分享到github并提供链接 其实我可以将它作为另一个问题提出并分享链接。可以吗? ***.com/questions/56219768/…【参考方案2】:按照这些步骤进行
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. 在您的活动中覆盖 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
输出
首页片段:
片段二:
片段树:
【讨论】:
感谢您的尝试,但是您提供的步骤不是必需的,并且产生了相同的结果。使用导航抽屉导航时,我应该能够控制要显示的图标。 原则上,抽屉导航应该有横向导航,这意味着项目处于同一级别。因此,当我使用抽屉从一个项目移动到另一个项目时,应该替换片段而不是添加到堆栈顶部。请参阅material.io/design/navigation/…。最后一件事,你只需要第三步,如果你想让拱形组件控制后退行为,第四步 当我点击后退箭头时,它会显示导航抽屉而不是返回到上一个片段。 @AVEbrahimi hasuoverride
onSupportNavigateUp()
方法就像我上面的代码
当我点击后退箭头时,它会显示导航抽屉而不是返回到上一个片段。 – 有什么解决方案吗,我不是在寻找解决方法【参考方案3】:
所以,我认为您可以使用 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 的情况下编写此代码,这可能会出错。但请接受这个想法。
希望对您有所帮助。
【讨论】:
虽然您的回答可能是一种解决方法,但我希望有一个解决方案可以自动执行此过程。这将需要跟踪片段以了解要执行的操作。这样,我将失去 Navigation Arch 组件的好处。以上是关于导航组件,控制何时显示汉堡包或返回图标的主要内容,如果未能解决你的问题,请参考以下文章
安卓导航组件。显示带有从箭头到十字的变形导航图标的全屏对话框