4

I have one problem. I need exactly this toolbar.

enter image description here

Toolbar must have centered title and color of up button must be different than color of title. For example I can achieve centered title with these lines of code.

     <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>

This is in my MainActivity

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

But I want setup toolbar with Jetpack Navigation Component for better and easier navigation. When I setup toolbar with these lines of code in my MainActivity this happens.

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

https://ibb.co/6v8PPmR (another image)

I have spent almost 4 hours with these. I have tried lot of solutions but nothing worked.

So, It is possible to center text in toolbar when using setupWithNavController or should I come up with my own custom solution ?

Shadow
  • 4,168
  • 5
  • 41
  • 72
miso01
  • 414
  • 6
  • 12
  • wrap your textView with relativeLayout and make it in center. Also use `supportActionBar.Title = ""` – Rahul Khurana Jul 23 '19 at 07:14
  • Centered title works when I setup it manually, but when I setup toolbar with navController then toolbar title is set automatically and it isn't centered. I want know how to center title when is set automatically using Navigation Component... – miso01 Jul 23 '19 at 07:37
  • I'm afraid currently there is no way to achieve this – Rahul Khurana Jul 23 '19 at 07:38
  • I will wait few days, maybe someone come up with solution. I think too that there is no way to do this. Maybe, I should come up with own solution using with some destinationListener or navigationListener and setup up button and title manually... – miso01 Jul 23 '19 at 07:42
  • check this [https://stackoverflow.com/a/42465387/4079010](https://stackoverflow.com/a/42465387/4079010) – Rahul Khurana Jul 23 '19 at 07:47
  • It doesn't work with navController, it works just with mentioned first way – miso01 Jul 23 '19 at 08:01
  • You can modify it according to your requirement. At least the above link will guide you through right way. – Rahul Khurana Jul 23 '19 at 08:04
  • How I can modify it ? I think code is good but it does nothing when toolbar is used with navController. – miso01 Jul 23 '19 at 08:15
  • did you see the if condition where it put the break? You need to modify it – Rahul Khurana Jul 23 '19 at 08:17
  • Yes, I see it. But I don't think that I should modify it. But when I'm using navController this code don't find textviews in toolbar. Textviews are 0 and code is at the end... – miso01 Jul 23 '19 at 08:40
  • @miso01, have you achieved this? if yes, how? – Kalpesh Wadekar Oct 22 '20 at 13:02

2 Answers2

2

My Early answer suggested using reflection but it's better not to work against the framework. So on further search found that You can do it as follows.

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

setTitle is an extension function on toolbar what it does it it sets the title as empty text and sets the title to our custom title textview(titletextview) in this case

Code for the extension function be

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
}

}

Code to generate title is taken from androidx.navigation.ui.AbstractAppBarOnDestinationChangedListener

v1n33th
  • 181
  • 2
  • 7
-1

I was facing the same issue and I was able to create a custom toolbar with the title text-centered this way. This method might be helpful if you want to use a custom font and size. I thought it might help someone. First, make sure you are using NoActionBar theme and set windowActionBar to false. Finally,in your onViewCreated() put this code.

    (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

makkhay gurung
  • 528
  • 1
  • 4
  • 15