导航组件,如何在导航抽屉中显示普通的向上/后退按钮而不是汉堡图标

如何解决导航组件,如何在导航抽屉中显示普通的向上/后退按钮而不是汉堡图标

我的活动中有三个顶级目标片段:

appBarConfiguration = AppBarConfiguration(
        setOf(
            R.id.trackerFragment,R.id.nutrientFragment,R.id.settingsFragment
        ),drawerLayout
    )

这意味着所有这些片段将显示汉堡按钮而不是正常的后退箭头。问题是我的应用程序中有一个“转到 Nutrient”按钮,可以导航到 NutrientFragment,这是一个顶级目的地。我希望这个片段在使用抽屉导航时仍然显示汉堡包图标,但在导航“转到营养”按钮时显示正常的后退/向上按钮。

我最初的想法是在导航到 NutrientFragment 时传递一个布尔值作为参数,在 onCreateView() 内部,根据布尔值,删除汉堡包图标或添加后退按钮。但这似乎有点丑陋且效率低下,特别是如果将来我添加更多可能存在相同问题的目的地。我也不知道如何“删除汉堡包图标并替换为正常的后退按钮”。关于如何实施的任何想法?我找到的所有答案要么是旧的已弃用的 Java 代码,要么不是我想要的。

谢谢。

解决方法

鉴于:

现在您有一个包含三个片段(trackerFragment、nutritionFragment 和 settingsFragment)的导航抽屉。

appBarConfiguration = AppBarConfiguration(
        setOf(
            R.id.trackerFragment,R.id.nutrientFragment,R.id.settingsFragment
        ),drawerLayout
    )

必填:

您想将汉堡保留在主片段 (NutrientFragment) 中,并用某些片段的 UP 按钮替换它。

解决方案:

假设 settingsFragment 是片段,则您需要使用 UP 按钮而不是汉堡。

首先从 appBarConfiguration 中删除此片段:

appBarConfiguration = AppBarConfiguration(
    setOf(
        R.id.trackerFragment,R.id.nutrientFragment
    ),drawerLayout
)

然后,为了控制 Burger 按钮,您需要将抽屉布局和 SupportActionBartoggle.isDrawerIndicatorEnabled 同步,这是一种方法:

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

R.string.open & R.string.close 是符号字符串,您可以在strings.xml 中创建它们:

<resources>
    <string name="open">Open</string>
    <string name="close">Close</string>
</resources>

toolBar 是工具栏,它从布局中膨胀并设置为 supportActionBarsetSupportActionBar()

然后,向导航添加侦听器以检测何时选择了 settingFragment,以便您可以使用 setToolbarNavigationClickListener 禁用汉堡的切换功能:

val toggle = getActionBarDrawerToggle(drawerLayout,toolbar) // replace  the `drawerLayout` & `toolbar` according to yours
navController.addOnDestinationChangedListener { _,destination,_ ->
    if (destination.id == R.id.settingsFragment)
        toggle.isDrawerIndicatorEnabled = false
}

当然,现在无论何时单击 UP 按钮都不起作用,要解决此问题,我们需要 Raised by: django.views.static.serve 以启用切换功能并导航回 Home 片段(假设 home 片段是 nutrientFragment):

toggle.setToolbarNavigationClickListener {
    toggle.isDrawerIndicatorEnabled = true
    navController.navigate(R.id.nutrientFragment)
}

预览:

这里的 Gallery 片段是 UP 按钮所在的位置:

,

我设法找到了解决方案。我将此变量添加到我的 MainActivity:

// If true,disable drawer and enable back/up button
private var isUpButton = false

还有这些方法:

// Disable drawer and enable the up button
fun useUpButton() {
    supportActionBar?.setHomeAsUpIndicator(
        androidx.appcompat.R.drawable.abc_ic_ab_back_material
    )
    drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
    isUpButton = true
}

// Enable the drawer and disable up button
private fun useHamburgerButton() {
    drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
    isUpButton = false
}

useUpButton() 用默认的向上图标替换汉堡包图标,锁定抽屉滑块并将 isUpButton 设置为 true。我也覆盖了 onOptionsItemsSelected:

// If isUpButton is true,and the home button is clicked,navigate up and
// enable drawer again,if false,just normal drawer behaviour
override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return if (isUpButton && item.itemId == android.R.id.home) {
        navController.navigateUp()
        useHamburgerButton()
        true
    } else super.onOptionsItemSelected(item)
}

因此,如果单击主页按钮(汉堡包图标或向上图标),并且将 isUpButton 设置为 true,则 Activity 将向上导航,就像正常的向上行为一样,并将 isUpButton 重置为 false,以便其他片段可以再次享受抽屉。

现在我需要做的就是使用这些方法来解决我的问题:我希望 NutrientFragment 仅在我导航到它而不使用抽屉时才显示“向上按钮”。为此,我需要为 nav_graph.xml 上的 NutrientFragment 目标创建一个参数:

<fragment
    android:id="@+id/nutrientFragment"
    android:name="com.example.elegantcalorietracker.ui.fragments.NutrientFragment"
    android:label="@string/nutrients"
    tools:layout="@layout/fragment_nutrient">
    <action
        android:id="@+id/action_nutrientFragment_to_trackerFragment"
        app:destination="@id/trackerFragment" />
    <argument
        android:name="upButtonNeeded"
        android:defaultValue="false"
        app:argType="boolean" />

并将其添加到 NutrientFragment 的 onCreateView() 方法中:

upButtonNeeded = arguments?.getBoolean("upButtonNeeded") ?: false
if (upButtonNeeded) {
    (activity as MainActivity).useUpButton()
}

现在,如果我在另一个片段中有一个导航到 NutrientFragment 的按钮,我需要做的就是将 true 作为参数传递给导航方法:

val argument = bundleOf("upButtonNeeded" to true)
this@TrackerFragment
     .findNavController()
     .navigate(
         R.id.action_trackerFragment_to_nutrientFragment,argument
     )

结果:

当使用抽屉导航到 NutrientFragment 时,汉堡包图标正常显示,但当以另一种方式导航到它时,如按钮,向上按钮显示:

Solution gif

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?