Playing with Toolbar in Android Development

Anna Scott
6 min readJul 6, 2023

--

Added in API Level 21, Toolbar could be thought as a step up from the action bar. Toolbar allows more customization in comparison with action bar. Toolbar achieves it by being a ViewGroup. As a view group, it could be placed anywhere in layout and individually styled. You can have more than one Toolbar. For example, take a look at the following xml file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />

<Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello from tool bar"
android:textColor="@color/black" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button inside Toolbar" />

</LinearLayout>

</Toolbar>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Another TextView" />

<Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second Toolbar"
android:textColor="@color/black" />

<SeekBar
android:layout_width="300dp"
android:layout_height="match_parent"
android:background="#FF0000" />

</LinearLayout>
</Toolbar>

</LinearLayout>

Here we have two Toolbars that are placed inside the LinearLayout and separated by the TextView. Each of our Toolbar contains a LinearLayout with the TextView inside of it, and the first one has a Button, and the second one has a SeekBar. We also retain theme-provided ActionBar. The following image is the result of above code on the screen:

Toolbar as Action bar

ActionBar is still valid option if all you need is a static bar at the top with back button and icons. However, if you need more freedom in styling, you can use Toolbar.

To start, we need to make sure to add AndroidX support library to build.gradle(Module:app) file:

dependencies {

implementation 'androidx.appcompat:appcompat:1.6.1'

}

Then, we need to disable ActionBar. To accomplish this let’s use Theme.AppCompat.Light.NoActionBar in /res/values/themes.xml file:

<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.PlayingWithToolbar" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>

<style name="Theme.PlayingWithToolbar" parent="Base.Theme.PlayingWithToolbar" />
</resources>

For the next step, we need to add our Toolbar to the layout file. We are going to place it at the top in a place of conventional ActionBar:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hi!!!"
android:background="#00FFFF">

<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="I am a toolbar!!!" />

</androidx.appcompat.widget.Toolbar>

</LinearLayout>

In our Java code in onCreate method we need to find our Toolbar by id and set it to act as ActionBar for that Activity method:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Find the toolbar view inside the activity layout
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// Sets the Toolbar to act as the ActionBar for this Activity window.
// Make sure the toolbar exists in the activity and is not null
setSupportActionBar(toolbar);

}

To add clickable items to our Toolbar we can the same way as with ActionBar. We will create XML menu resource file in /res/menu directory:

<?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/cat"
android:icon="@drawable/cat"
app:showAsAction="always"/>

<!-- Settings, should always be in the overflow -->
<item android:id="@+id/dog"
android:icon="@drawable/dog"
app:showAsAction="always"/>

</menu>

Just like with ActionBar we override onCreateOptionsMenu method to inflate menu icons:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.toolbar_menu, menu);
return true;
}

To add response to clicks on our icons we override onOptionsItemsSelected method:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.cat)
Toast.makeText(getApplicationContext(), "Cat", Toast.LENGTH_SHORT).show();
if (item.getItemId() == R.id.dog)
Toast.makeText(getApplicationContext(), "Dog", Toast.LENGTH_SHORT).show();
return true;
}

This is how our ToolBar looks and acts:

Setting image as Up navigation

We need to make sure that image that we want to use is the right size to be used as an icon in our Toolbar. To achieve this we will import it as image asset:

Make sure to give your image descriptive name.

Notice, that your image is going to be placed in mipmap folder. The same folder as launching icon for your app.

In Java code in onCreate method we will use setHomeAsUpIndidcator method to set as alternative drawable to be dispayed in place for up navigation. We will pass true to the method setDisplayHomeAsUpEnable to go up one level:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Find the toolbar view inside the activity layout
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// Sets the Toolbar to act as the ActionBar for this Activity window.
// Make sure the toolbar exists in the activity and is not null
setSupportActionBar(toolbar);

ActionBar actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.setHomeAsUpIndicator(R.mipmap.dog_house);
actionBar.setDisplayHomeAsUpEnabled(true);
}

We need to implement the correct behavior in onOptionsItemSelected method:

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}

Disappearing Toolbar

We can have the ToolBar hide as the user scrolls down and reappear as the user scrolls back up.

To achieve this we will set up CoordinatorLayout and then wrap our toolBar in AppBarLayout.

dependencies {
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
}
<?xml version="1.0" encoding="utf-8"?><!-- CoordinatorLayout is used to create scrolling and "floating" effects within a layout -->
<!-- This is typically the root layout which wraps the app bar and content -->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<!-- AppBarLayout is a wrapper for a Toolbar in order to apply scrolling effects. -->
<!-- Note that AppBarLayout expects to be the first child nested within a CoordinatorLayout -->
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar">


<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#00FFFF"
app:layout_scrollFlags="scroll|enterAlways" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

It is important to set a scrollFlag like it is done in the last line of the above code snipet: app:layout_scrollFlags=”scroll|enterAlways.

Disappearing Toolbar with Image

We can have an image that disappears as we scroll leaving a Toolbar which in its turn also dissapears as scrolling continues.

Start by adding dependency to build.gradle(Module:app):

dependencies {
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
}

Inside AppBarLayout we need to add CollapsingToolbarLayout and put ImageView inside CollapsingToolbarLayout.

<?xml version="1.0" encoding="utf-8"?><!-- CoordinatorLayout is used to create scrolling and "floating" effects within a layout -->
<!-- This is typically the root layout which wraps the app bar and content -->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<!-- AppBarLayout is a wrapper for a Toolbar in order to apply scrolling effects. -->
<!-- Note that AppBarLayout expects to be the first child nested within a CoordinatorLayout -->

<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="#00FFFF"
app:layout_scrollFlags="scroll|enterAlways">


<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@drawable/small_dog"
app:layout_collapseMode="parallax" />

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="pin">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi, I am a ToolBar!" />

</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

In the above code snippet I would like to point out the attribute app:contentScrim that allows to set color of Toolbar. The attribute app:layout_collapseMode is responsible for Toolbar’s behavior.

For now I am finished exploring Toolbar’s behavior, however I am interested if you know of any other cool things you can do with Toolbar:)

Happy coding my dear coding friends!

All the code could be found here:

--

--