Reputation: 462
I have one problem. I need exactly this toolbar.
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 ?
Upvotes: 4
Views: 4842
Reputation: 341
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
Upvotes: 2
Reputation: 538
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)
Upvotes: -1