使用Jetpack Navigation组件创建自定义工具栏

4

我有一个问题。我需要这个工具栏。

enter image description here

工具栏必须有居中的标题,并且向上按钮的颜色必须与标题的颜色不同。例如,我可以使用以下代码实现居中标题。

     <androidx.appcompat.widget.Toolbar
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:theme="?attr/actionBarTheme"
            android:minHeight="?attr/actionBarSize"
            android:id="@+id/tb_main"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:gravity="center">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:id="@+id/tb_title_main"
                android:textColor="@color/black_80"
                android:textSize="20sp"
                />

    </androidx.appcompat.widget.Toolbar>

这是我的MainActivity

    val toolbar = binding.tbMain
    toolbar.tb_title_main.text = "Centered Text "
    setSupportActionBar(toolbar)
    supportActionBar?.setDisplayShowTitleEnabled(false)

但我希望使用Jetpack Navigation组件设置工具栏以实现更好、更轻松的导航。当我在MainActivity中使用以下代码设置工具栏时,会发生这种情况。

    val navController = findNavController(R.id.nav_host_fragment)
    val toolbar = binding.tbMain
    setSupportActionBar(toolbar)
    val appBarConfiguration = 
    AppBarConfiguration(navController.graph)
    toolbar.setupWithNavController(navController, 
    appBarConfiguration)

这里是另一张图片

我花了将近4小时的时间,尝试了许多解决方案,但都没有奏效。

因此,在使用setupWithNavController时,是否有可能居中工具栏中的文本,或者我应该想出自己的定制解决方案?


将您的textView用relativeLayout包装并使其居中。同时使用supportActionBar.Title = "" - Rahul Khurana
当我手动设置居中标题时,居中标题可以正常工作,但是当我使用navController设置工具栏时,工具栏标题会自动设置并且不居中。我想知道如何在使用导航组件自动设置标题时将其居中... - miso01
请查看此链接:https://stackoverflow.com/a/42465387/4079010 - Rahul Khurana
它不能与navController一起使用,只能使用提到的第一种方式。 - miso01
您可以根据您的需求进行修改。至少上述链接将指导您正确的方法。 - Rahul Khurana
显示剩余6条评论
2个回答

2

我之前的回答建议使用反射,但最好不要违背框架。所以在进一步搜索后发现可以按照以下方式实现。

navHostFragment.navController.addOnDestinationChangedListener { _, destination, arguments ->
        binding.toolBarHome.setTitle(destination.label, titleTextView, arguments)
    }

setTitle是工具栏上的扩展函数,它的作用是将标题设置为空文本,并将标题设置为我们自定义的标题文本视图(titletextview)。

扩展函数的代码如下:

fun Toolbar.setTitle(label: CharSequence?, textView: TextView, arguments: Bundle?) {
if (label != null) {
    // Fill in the data pattern with the args to build a valid URI
    val title = StringBuffer()
    val fillInPattern = Pattern.compile("\\{(.+?)\\}")
    val matcher = fillInPattern.matcher(label)
    while (matcher.find()) {
        val argName = matcher.group(1)
        if (arguments != null && arguments.containsKey(argName)) {
            matcher.appendReplacement(title, "")
            title.append(arguments.get(argName).toString())
        } else {
            return //returning because the argument required is not found
        }
    }
    matcher.appendTail(title)
    setTitle("")
    textView.text = title
}

从androidx.navigation.ui.AbstractAppBarOnDestinationChangedListener中获取代码以生成标题。


-1

我曾经遇到同样的问题,但是我成功地创建了一个自定义工具栏,并将标题居中。如果您想使用自定义字体和大小,这种方法可能会有所帮助。我认为这可能会对某些人有所帮助。首先,请确保您正在使用NoActionBar主题,并将windowActionBar设置为false。最后,在您的onViewCreated()中放置以下代码。

    (activity as AppCompatActivity).supportActionBar?.displayOptions =
        androidx.appcompat.app.ActionBar.DISPLAY_SHOW_CUSTOM

    // inflating your custom view
    // not quite sure what I should put for root so I have put "null". I am guessing we need to put the root view from `onViewCreated()` ?  
    val customView = layoutInflater.inflate(R.layout.custom_toolbar, null)

    // setting the whole layout match parent. For some reason, doing match parent from xml wasn't working 
    val layoutParams = androidx.appcompat.app.ActionBar.LayoutParams(
        androidx.appcompat.app.ActionBar.LayoutParams.MATCH_PARENT,
        androidx.appcompat.app.ActionBar.LayoutParams.MATCH_PARENT
    )

    // applying the customview  
    (activity as AppCompatActivity).supportActionBar?.setCustomView(customView, layoutParams)

    // in case you want to change the text yourself 
    toolBarTitle = customView.findViewById(R.id.customTitle)

Here's the final result


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接