如何为工具栏设置我自己的菜单和返回图标? [英] How to set my own Menu and Back icons for Toolbar?

查看:22
本文介绍了如何为工具栏设置我自己的菜单和返回图标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用导航组件自动处理应用程序是否应显示菜单按钮以显示打开导航抽屉或返回按钮返回主页(例如仪表板):

I use Navigation Component which automatically handles if app should display Menu button to display to open navigation drawer or Back button to return back to home (dashboard for example):

    setupActionBarWithNavController(navController, appBarConfiguration)
    binding.navigationDrawer.setupWithNavController(navController)
    binding.bottomNavigationView.setupWithNavController(navController)

navController.addOnDestinationChangedListener { _, destination, bundle ->... }

原来如此

导航组件会自动设置这些图标.

Navigation Component automatically sets those icons.

如何覆盖每个图标?我需要覆盖菜单"和后退"按钮图标.

How can I override each icon? I need to override Menu and Back buttons icon.

请不要提及只设置一个图标的方法...

Please don't mention methods which only set one icon...

推荐答案

导航组件会自动设置这些图标.

Navigation Component automatically sets those icons.

如何覆盖每个图标?我需要覆盖菜单"和后退"按钮图标.

How can I override each icon? I need to override Menu and Back buttons icon.

因此,现在您可以在片段之间导航,然后从 AppBarConfiguration 的顶部层次结构中删除要显示后退/向上按钮的片段.

So, now you can navigate between the fragments, upon that you removed the fragment that you want to show the back/up button from the top hierarchy of the AppBarConfiguration.

假设您有 3 个片段:主页、画廊和幻灯片;并且您希望在图库片段上显示后退按钮,而在其他片段中显示普通菜单按钮.

Assuming you've 3 fragments: home, gallery, and slideshow; and you wish to show the back button on the gallery fragment, and the normal menu button in others.

所以,你会有类似的东西:

So, you'd have something like:

val appBarConfiguration = AppBarConfiguration(
    setOf(
        R.id.nav_home, R.id.nav_slideshow
    ), drawerLayout
)

setupActionBarWithNavController(navController, appBarConfiguration)

现在我们需要在不使用addOnDestinationChangedListener的情况下更改图标.

Now we need to change the icons without using addOnDestinationChangedListener.

可以使用supportActionBar.setHomeAsUpIndicator(drawableRes)

但是,实际上图标需要手动更改,因为这不是抽屉布局的默认行为,导航组件对此一无所知;所以你可以使用抽屉布局的 API 来做到这一点.

But, actually icons need to be changed manually as this is not the default behavior of the drawer layout, and navigation components has no idea about that; so you can do that using the APIs of the drawer layout.

因此,首先使用 binding.drawerLayout.addDrawerListener(toggle) 注册此图标的侦听器,这需要创建 ActionBarDrawerToggle,因此将其保存在本地活动中,剩下的在代码注释中:

So, first register a listener to this icon with binding.drawerLayout.addDrawerListener(toggle) and this requires to create the ActionBarDrawerToggle, so save it locally in the activity, and the rest is in the code comments:

class MainActivity : AppCompatActivity() {

    private var toggle: ActionBarDrawerToggle? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Intialization code is omitted....
        
        toggle = getActionBarDrawerToggle(binding.drawerLayout, binding.appBarMain.toolbar).apply {
            setToolbarNavigationClickListener {
                // Back to home fragment for any hit to the back button
                navController.navigate(R.id.nav_home)
            }
            // Intialize the icon at the app start
            enableHomeBackIcon(false)
        }
    }

    fun enableHomeBackIcon(enabled: Boolean) {
        // Enable/Disable opening the drawer from the start side
        toggle?.isDrawerIndicatorEnabled = !enabled
       
        // Change the default burger icon
        supportActionBar?.setHomeAsUpIndicator(
            if (enabled) R.drawable.back_arrow
            else R.drawable.burger
        )
    }

    private fun getActionBarDrawerToggle(
        drawerLayout: DrawerLayout,
        toolbar: Toolbar
    ): ActionBarDrawerToggle {
        toggle = ActionBarDrawerToggle(
            this,
            drawerLayout,
            toolbar,
            R.string.open,
            R.string.close
        )
        drawerLayout.addDrawerListener(toggle!!)
        toggle?.syncState()
        return toggle as ActionBarDrawerToggle
    }

}

并且根据您的要求,您可以使用抽屉片段生命周期方法,而不是使用 addOnDestinationChangedListener;我将使用 onViewCreated():

And as per your requirement, instead of using addOnDestinationChangedListener, you can utilize the drawer fragments lifecycle method; I will be using onViewCreated():

家庭和幻灯片片段:通过活动禁用后退按钮:

Home & Slideshow fragment: Disable the back button through the activity:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    (requireActivity() as MainActivity).enableHomeBackIcon(false)
}

图库片段:通过活动启用后退按钮:

Gallery fragment: Enable the back button through the activity:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    (requireActivity() as MainActivity).enableHomeBackIcon(true)
}

这篇关于如何为工具栏设置我自己的菜单和返回图标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆