Developing a unique user interface is a key aspect of creating a successful Android application. Toolbar (toolbar) replaces the outdated one ActionBar and offers flexibility in customizing the appearance and functionality. Unlike standard solutions, a custom toolbar allows you to place a logo, search bar, navigation buttons or even animations - everything is limited only by your imagination and design requirements.
This article is suitable for both beginners and experienced developers. We will look at the process of creating a toolbar from scratch: from adding a dependency in build.gradle to dynamically managing elements via Kotlin/Java. We will pay special attention integration with the system navigation bar and handling click eventsto this, which often causes difficulties for beginners. Ready to turn a standard header into a unique element of your application?
1. Preparing the project: dependencies and structure
Before starting the visual part, make sure that your project is configured correctly. Modern versions Android Studio Giraffe (2022+) already include the necessary libraries, but for stability it is recommended to explicitly specify the dependency Material Components in the file build.gradle (Module: app):
dependencies {implementation 'com.google.android.material:material:1.9.0'
// Other dependencies...
}
After synchronizing the project (Sync Now), check for the presence of the style Theme.MaterialComponents in file themes.xml. If it is not there, add:
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
</style>
โ ๏ธ Attention: Versions of libraries in build.gradle may differ in new releases. Always check the current version numbers on the official website of Android Developers.
Structure of project files for toolbar:
- ๐
res/layout/โ here will be the toolbar XML markup (toolbar_custom.xml) - ๐
res/menu/โ menu files for toolbar buttons (menu_toolbar.xml) - ๐
res/values/โstyles and colors (colors.xml,styles.xml)
2. Creating toolbar markup in XML
The basis of a custom toolbar is an XML markup file. Create a new file res/layout/toolbar_custom.xml and define the structure in it:
<?xml version="1.0" encoding="utf-8"?><androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/customToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<ImageView
android:id="@+id/toolbarLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher_foreground"
android:layout_gravity="start"/>
<TextView
android:id="@+id/toolbarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My App"
android:textColor="@android:color/white"
android:textSize="18sp"
android:layout_gravity="center_horizontal"/>
</androidx.appcompat.widget.Toolbar>
Key markup attributes:
- ๐น
?attr/actionBarSizeโautomatically adjusts the height to system recommendations - ๐น
android:elevationโadds a shadow for the โraisedโ panel effect - ๐น
app:popupThemeโcontrols the style of drop-down menus - ๐น
android:themeโseparate theme for toolbar elements
Use android:layout_gravity to position elements inside the toolbar. Values start, center_horizontal and end will help position the logo, title and action buttons symmetrically.
3. Integrating toolbar into Activity/Fragment
The created toolbar needs to be connected to Activity or Fragment and replace the standard one ActionBar. In the markup file of your activity (activity_main.xml), add toolbar as the first element:
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/toolbar_custom"
android:id="@+id/toolbar"/>
</androidx.constraintlayout.widget.ConstraintLayout>
In the code Activity (for example Kotlin) configure the toolbar as the main panel:
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Setting up the toolbar
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.apply {
setDisplayShowTitleEnabled(false) // Hide the standard one header
setDisplayHomeAsUpEnabled(true) // Enable the "Back" button
}
// Access to custom elements
val logo = findViewById<ImageView>(R.id.toolbarLogo)
val title = findViewById<TextView>(R.id.toolbarTitle)
}
}
โ ๏ธ Attention: If you use Fragment, it is better to configure the toolbar in method onViewCreated parent Activityto avoid code duplication and conflicts with the system navigation bar.
4. Adding menus and processing clicks
Toolbar supports the standard Android menu, which is defined in the file res/menu/menu_toolbar.xml:
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:title="Search"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_settings"
android:icon="@drawable/ic_settings"
android:title="Settings"
app:showAsAction="never"/>
</menu>
To make the menu appear in the toolbar, override the method onCreateOptionsMenu in Activity:
override fun onCreateOptionsMenu(menu: Menu?): Boolean {menuInflater.inflate(R.menu.menu_toolbar, menu)
return true
}
Processing clicks on menu items is implemented in method onOptionsItemSelected:
override fun onOptionsItemSelected(item: MenuItem): Boolean {return when (item.itemId) {
R.id.action_search -> {
// Search logic
true
}
R.id.action_settings -> {
startActivity(Intent(this, SettingsActivity::class.java))
true
}
else -> super.onOptionsItemSelected(item)
}
}
| Menu attribute | Description | Example value |
|---|---|---|
app:showAsAction |
Controls the visibility of the element | ifRoom, never, always |
android:icon |
Icon element | @drawable/ic_search |
android:title |
Text label (for the drop-down menu) | "Settings" |
android:id |
Identifier for click processing | @+id/action_settings |
Icons are displayed correctly|"ifRoom" elements are visible in the panel|The drop-down menu opens by click on three points|Click handlers work without errors-->
5. Styling and responsive design
The appearance of the toolbar is configured through styles and attributes. First, define the color resources in res/values/colors.xml:
<color name="colorPrimary">#6200EE</color><color name="colorPrimaryDark">#3700B3</color>
<color name="colorOnPrimary">#FFFFFF</color>
Apply them to the toolbar through the style in res/values/styles.xml:
<style name="CustomToolbarStyle" parent="Widget.MaterialComponents.Toolbar"><item name="android:background">@color/colorPrimary</item>
<item name="titleTextColor">@color/colorOnPrimary</item>
<item name="subtitleTextColor">@color/colorOnPrimary</item>
<item name="navigationIconTint">@color/colorOnPrimary</item>
</style>
For adaptability, use dimension resources. Create a file res/values/dimens.xml:
<resources><dimen name="toolbar_height">?attr/actionBarSize</dimen>
<dimen name="toolbar_margin_horizontal">16dp</dimen>
<dimen name="toolbar_logo_size">32dp</dimen>
</resources>
Apply them in the toolbar markup:
<ImageViewandroid:layout_width="@dimen/toolbar_logo_size"
android:layout_height="@dimen/toolbar_logo_size"
android:layout_marginStart="@dimen/toolbar_margin_horizontal"/>
How to make a transparent toolbar?
To make the toolbar transparent, set android:background="@android:color/transparent" and delete android:elevation. To correctly display the content under the toolbar, add to the activity markup android:fitsSystemWindows="true" for the root layout.
6. Dynamic control of the toolbar
Toolbar can be modified directly while the application is running. For example, change the title or hide/show elements:
// Changing the titletoolbarTitle.text = "New title"
// Hiding/showing the logo
toolbarLogo.visibility = View.GONE // or View.VISIBLE
// Dynamically adding a menu
toolbar.inflateMenu(R.menu.additional_menu)
To animate changes, use ViewPropertyAnimator:
toolbar.animate().alpha(0f)
.setDuration(300)
.withEndAction {
toolbar.visibility = View.GONE
}
.start()
An example of dynamically changing the background color when scrolling (using CollapsingToolbarLayout):
<com.google.android.material.appbar.CollapsingToolbarLayoutandroid:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
</com.google.android.material.appbar.CollapsingToolbarLayout>
โ ๏ธ Attention: When dynamically changing the height of the toolbar (layout_params.height), do not forget to callrequestLayout()to correctly recalculate the markup. Otherwise, the elements may overlap each other.
Use CollapsingToolbarLayout to create parallax effects and smoothly change the height of the toolbar when scrolling - this is a standard approach for modern applications with Material Design.
7. Optimizing performance
Incorrect implementation of the toolbar can lead to lags when scrolling or increased rendering time. Follow these recommendations:
- ๐ Avoid complex nested hierarchies View inside the toolbar. Optimally, no more than 3 levels of nesting.
- ๐ Use
VectorDrawablefor icons instead of raster images (PNG). - ๐ Cache references to toolbar elements (
findViewById) into class variables so as not to look for them again. - ๐ For animations, prefer
ObjectAnimatorinstead ofValueAnimatorโit is optimized for performance c View.
Check performance using Android Profiler v Android Studio:
- Open
View โ Tool Windows โ Profiler. - Run the application and interact with the toolbar.
- View graphs CPU and Memory โsharp jumps may indicate problems.
An example of optimized code for lazy initialization of toolbar elements:
private lateinit var toolbarLogo: ImageViewprivate fun initToolbar() {
if (!::toolbarLogo.isInitialized) {
toolbarLogo = findViewById(R.id.toolbarLogo)
}
// Next, working with toolbarLogo
}
8. solutions
Even experienced developers encounter problems when working with toolbar. Here are typical errors and ways to fix them:
| Problem | Cause | Solution |
|---|---|---|
| Toolbar not working displayed | Not called setSupportActionBar(toolbar) |
Check the method call in onCreate |
| The "Back" button does not work | Not installed setDisplayHomeAsUpEnabled(true) |
Add a line to the toolbar setting |
| Menu is not shown | Not overridden onCreateOptionsMenu |
Implement the method in Activity |
| Colors are not applied | Style conflict in themes.xml |
Check the parent style (parent) |
| Elements overlap | Irregular layout_gravity or margins |
Use ConstraintLayout for precise positioning |
If the toolbar overlaps the content, add a top padding for the main layout using android:paddingTop="?attr/actionBarSize" or use android:fitsSystemWindows="true".
To debug the toolbar layout, enable the "Layout Inspector" mode in Android Studio (Tools โ Layout Inspector). This will help visualize the hierarchy of elements and identify problems with positioning.
FAQ: Frequently asked questions about custom toolbar
Is it possible to use multiple toolbars in one Activity?
Yes, but it is recommended to avoid this as it violates the principles Material Design. If you need multiple panels, consider a TabLayout or BottomNavigationView bottom panel. If you still need several toolbars, place them in LinearLayout with a vertical orientation and control visibility through View.GONE/VISIBLE.
How to add a search string to a toolbar?
Use SearchView in the toolbar menu. In the file menu_toolbar.xml add:
<itemandroid:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:title="Search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/>
Then set up a handler in onCreateOptionsMenu:
val searchItem = menu?.findItem(R.id.action_search)val searchView = searchItem?.actionView as SearchView
searchView.queryHint = "Enter a query..."
Why icons Menus are not displayed in the light theme?
This is due to a color conflict. By default, menu icons inherit the color of the toolbar text. Add a toolbar to the style:
<item name="actionMenuTextColor">@color/colorOnPrimary</item>
<item name="android:textColorSecondary">@color/colorOnPrimary</item>
Or explicitly specify the color of the icons in the code:
toolbar.overflowIcon?.setTint(ContextCompat.getColor(this, R.color.colorOnPrimary))
How to make a toolbar transparent with a gradient?
Create a gradient file in res/drawable/gradient_toolbar.xml:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#880000FF"
android:endColor="#00000000"
android:angle="90"/>
</shape>
Then apply it to the toolbar:
<androidx.appcompat.widget.Toolbar...
android:background="@drawable/gradient_toolbar"/>
Is it possible to animate the change of icons in the toolbar?
Yes, use AnimatedVectorDrawable or TransitionDrawable. Example with TransitionDrawable:
- Create two layers in
res/drawable/transition_icon.xml: - Apply animation in code:
<transition xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/ic_old" />
<item android:drawable="@drawable/ic_new" />
</transition>
val transition = ContextCompat.getDrawable(this, R.drawable.transition_icon) as TransitionDrawabletoolbarLogo.setImageDrawable(transition)
transition.startTransition(300) // Duration in ms