Action Bar

The action bar is an important design element, usually at the top of each screen in an app, that provides a consistent familiar look between Android apps. It is used to provide better user interaction and experience by supporting easy navigation through tabs and drop-down lists. It also provides a space for the app or activity's identity, thus enabling the user to know their location in the app, and easy access to the actions that can be performed.

The action bar was introduced in Android 3.0, although support for older versions can be achieved by using the Android Support Library. Before its release, the Options Menu was usually used to provide the actions and functionality that are now put on the action bar. The action bar is included by default in all activities for apps with a minSdkVersion of 11. You can disable it and opt to only use the options menu, but for better user experiences it's better to use the action bar as it is visible to the user, while the options menu needs the user to request it and the user might not be aware of its existence in the first place.


Let's create an example, first we will create main.xml into res/menu folder:

main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/mnuSpeak"
        android:icon="@android:drawable/ic_btn_speak_now"
        android:title="Speak"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/mnuCall"
        android:icon="@android:drawable/ic_menu_call"
        android:title="Call Someone"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/mnuDone"
        android:title="All Ok"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/mnuDelete"
        android:icon="@android:drawable/ic_delete"
        android:title="Delete"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_settings"
        android:title="Settings"
        app:showAsAction="never" />
</menu>

There are four things that are needed to be configured for every menu item:

  • android:id: attribute specifies the id of the menu item. This works like ids anywhere else in the Android app. An android:id value starting with a @+id/ will create a constant in the R.menu constant collection
  • android:title: attribute value contains the title of the menu item
  • android:icon: attribute references an icon in the drawable directories
  • android:showAsAction: This attribute indicates how the given item should be portrayed in the action bar. We can choose from any of the flags always, ifRoom, never, withText. We can use multiple attribute with '|' sign.

please note in AndroidManifest.xml set activity theme android:theme="@style/AppTheme" as:

AndroidManifest.xml
<activity
    android:name=".MainActivity"
    android:label="@string/title_activity_main"
    android:theme="@style/AppTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Now Add and handle action's of menu's in MainActivity.java as:

MainActivity.java
package com.theitbulls.actionbarex;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.mnuCall:
                Toast.makeText(this, "Clicked on Call Menu", Toast.LENGTH_SHORT).show();
            case R.id.mnuDelete:
                Toast.makeText(this, "Clicked on Delete Menu", Toast.LENGTH_SHORT).show();
            case R.id.mnuDone:
                Toast.makeText(this, "Clicked on Done Menu", Toast.LENGTH_SHORT).show();
            case R.id.mnuSpeak:
                Toast.makeText(this, "Clicked on Speak Menu", Toast.LENGTH_SHORT).show();
        }
        return false;
    }
}


The action bar consists of:

  • App Icon: This is used to identify your app with a logo or icon.
  • View Control: This can also be used to identify the app or the specific activity the user is on by the title. If your app has different views, it can also be used to display these and allow for easy switching between views.
  • Action Buttons: These are used to display the most important and/or often used actions. If there isn't enough space to show all of the action buttons, those that don't fit are automatically moved to the action overflow.
  • Action Overflow: This is used for the lesser used actions.

Hiding the Action Bar

You might not want to have the action bar visible at all times to the user. A common example to this is the Gallery app which hides the action bar when the user is looking at an image and shows the action bar when they touch the image. To toggle action bar visibility on touch, add the following to your activity file.

MainActivity.java
package com.theitbulls.actionbarex;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
    private boolean touched;

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

        findViewById(R.id.rlMain).setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            toggleActionBar();
        }
        return false;
    }

    private void toggleActionBar() {
        if (touched) {
            getSupportActionBar().show();
        } else {
            getSupportActionBar().hide();
        }

        touched = !touched;
    }
}

Add android:id="@+id/rlMain to content_main.xml for RelativeLayout


Adding the Up Navigation

All screens in your app that are not the main entrance to your app (the "Main or First" screen) should offer the user a way to navigate to the logical parent screen in the app's hierarchy by pressing the Up button in the action bar. Starting in API level 14, you can declare the logical parent of each activity by specifying the android:parentActivityName attribute in the activity element in the manifest file.

To support lower versions, include the Support Library and specify the parent activity as the value for android.support.PARENT_ACTIVITY, matching the android:parentActivityName attribute.

AndroidManifest.xml add AnotherActivity.java with parent attributes:

<activity
    android:name=".AnotherActivity"
    android:launchMode="singleTop"
    android:parentActivityName=".MainActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity" />
</activity>


AnotherActivity.java
package com.theitbulls.actionbarex;

import android.os.Bundle;
import android.view.Menu;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class AnotherActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.another_activity);

        if(getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }
    }
}


Adding search action on ActionBar:

Action views are interactive widgets that appear within the action bar as a substitute for action buttons. They allow occasionally used UI items to be placed on the action bar, thus avoiding unnecessary consumption of screen space and switching of activities to use them.

To declare an action view, use either the actionLayout or actionViewClass attribute to specify either a layout resource or widget class to use, respectively. As a quick example, to add a androidx.appcompat.widget.SearchView widget to our example, modify the search action in.

We add item for search into res/menu/main.xml menu file as:

<item android:id="@+id/mnuSearch"
    android:icon="@android:drawable/ic_menu_search"
    android:title="@android:string/search_go"
    app:showAsAction="always|collapseActionView"
    app:actionViewClass="androidx.appcompat.widget.SearchView" />

Action on SearchView menu item:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    MenuItem mnuSearch = menu.findItem(R.id.mnuSearch);

    final SearchView searchView = (SearchView) mnuSearch.getActionView();
    if(searchView != null) {
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                Toast.makeText(MainActivity.this, "You search for: " + searchView.getQuery(), Toast.LENGTH_SHORT).show();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                return false;
            }
        });
    }
    return true;
}


Custom Menu:

We will create an example to demonstrate, how to create a custom action bar in Android. Let's create layout/custom_menu.xml containing email, edit and send button as:

layout/custom_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.AppCompatImageButton
        android:id="@+id/mnuSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:src="@android:drawable/ic_menu_send" />

    <androidx.appcompat.widget.AppCompatImageButton
        android:id="@+id/mnuEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:src="@android:drawable/sym_action_email" />

    <androidx.appcompat.widget.AppCompatImageButton
        android:id="@+id/mnuEdit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:src="@android:drawable/ic_menu_edit" />

</RelativeLayout>

Now create CustomMenuActivity.java and replace deafult ActionBar with custom ActionBar, please make sure before replace custom menu layout call getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM) now find example:

CustomMenuActivity.java
package com.theitbulls.actionbarex;

import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;

public class CustomMenuActivity extends AppCompatActivity implements View.OnClickListener {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.custom_menu_activity);

        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

            getSupportActionBar().setCustomView(R.layout.custom_menu);

            View cutomView = getSupportActionBar().getCustomView();
            cutomView.findViewById(R.id.mnuEmail).setOnClickListener(this);
            cutomView.findViewById(R.id.mnuEdit).setOnClickListener(this);
            cutomView.findViewById(R.id.mnuSend).setOnClickListener(this);
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.mnuEdit:
                Toast.makeText(this, "You clicked on edit custom menu", Toast.LENGTH_SHORT).show();
                break;
            case R.id.mnuEmail:
                Toast.makeText(this, "You clicked on email custom menu", Toast.LENGTH_SHORT).show();
                break;
            case R.id.mnuSend:
                Toast.makeText(this, "You clicked on send custom menu", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}


Download complete example

Download: ActionBar and Custom ActionBar Example