ZOFTINO.COM android and web dev tutorials

Enhance Action Bar Functionality with Action View

Action bar in your android app is the place where important actions are placed so that user can easily find and perform actions. Action bar can be further enhanced with action views.

Action views provide views where user can input and perform actions. With action view you can provide intractable actions on app bar.

Support library provides action view widgets such as ActionMenuView and SearchView. To add an action view to app bar, you need to add either actionViewClass or actionLayout to menu item in menu xml file.

In this article, I am going to show how to use ActionMenuView widget, SearchView widget and custom action view.

ActionMenuView widget

Using ActionMenuView, you can present series of actions in view. Below example shows how to use ActionMenuView to display sub actions in app bar. In this ActionMenuView example, clicking ActionMenuView action displays sub actions on app bar. Below image highlights ActionMenuView in red circle and on clicking it, sub menu items are shown on app bar.

ActionMenuView example

Steps to use ActionMenuView widget

  • Enable action bar
  • Create ActionMenuView item in menu xml file
  • Override onCreateOptionsMenu method in activity to configure ActionMenuView and set listeners

MainActivity

package com.zoftino.actionview;

import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.ActionMenuView.OnMenuItemClickListener;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

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

        Toolbar myToolbar = (Toolbar) findViewById(R.id.z_toolbar);
        setSupportActionBar(myToolbar);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.av_menu, menu);

        MenuItem menuItem = menu.findItem(R.id.action_menu);
        ActionMenuView amView =
                (ActionMenuView) MenuItemCompat.getActionView(menuItem);

        Menu menuObject = amView.getMenu();
        inflater.inflate(R.menu.sub_menu, menuObject);

        amView.setOnMenuItemClickListener( new OnMenuItemClickListener(){
           public boolean onMenuItemClick(MenuItem item){
               TextView textView = (TextView) findViewById(R.id.action_nme);

               switch (item.getItemId()) {

                   case R.id.action_email:
                       textView.setText("Email clicked");
                       return true;
                   case R.id.action_forum:
                       textView.setText("Forum clicked");
                       return true;
                   case R.id.action_comment:
                       textView.setText("Comment clicked");
                       return true;
                   case R.id.action_setting:
                       textView.setText("Settings clicked");
                       return true;

                   default:
                       return true;
               }

            }
        });
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        TextView textView = (TextView) findViewById(R.id.action_nme);

        switch (item.getItemId()) {

            case R.id.action_settings:
                textView.setText("Settings clicked");
                return true;

            default:
                return super.onOptionsItemSelected(item);

        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.zoftino.actionview.MainActivity">
    <android.support.v7.widget.Toolbar android:id="@+id/z_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp"></android.support.v7.widget.Toolbar>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/z_toolbar"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="50dp"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin">

        <TextView
            android:text=""
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/action_nme"></TextView>
    </LinearLayout>


</RelativeLayout>

av_menu.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_settings" android:icon="@drawable/settings" android:title="@string/settings" app:showAsAction="never"></item>
    <item android:id="@+id/action_menu"
        android:title="@string/action_menu"
        android:icon="@drawable/menu"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionViewClass="android.support.v7.widget.ActionMenuView"></item>
</menu>

sub_menu.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_email" android:icon="@drawable/email" android:title="@string/email" app:showAsAction="always"></item>
    <item android:id="@+id/action_forum" android:icon="@drawable/forum" android:title="@string/forum" app:showAsAction="always"></item>
    <item android:id="@+id/action_comment" android:icon="@drawable/comment" android:title="@string/comment" app:showAsAction="always"></item>
    <item android:id="@+id/action_setting" android:icon="@drawable/settings" android:title="@string/settings" app:showAsAction="always"></item>

</menu>

SearchView widget

You can provide search functionality on app bar in your app using SearchView widget as action view. SearchView widget displays search box on clicking it and it takes search query, submits search request and shows search help and results.

SearchView works with searchable activity to provide complete search functionality. Below example shows how to configure SearchView so that it can be used with searchable activity to provide search functionality.

To configure SearchView, you need to create SearchView item in menu xml file and override onCreateOptionsMenu method in activity class.

android action view searchview example

Activity

package com.zoftino.actionview;

import android.app.SearchManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;


public class ShowSearchActivity extends AppCompatActivity {

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

        Toolbar myToolbar = (Toolbar) findViewById(R.id.sv_toolbar);
        setSupportActionBar(myToolbar);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.search_view_menu, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView =
                (SearchView) MenuItemCompat.getActionView(searchItem);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

        return super.onCreateOptionsMenu(menu);
    }
}

search_view_menu.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_settings" android:icon="@drawable/settings" android:title="@string/settings" app:showAsAction="never"></item>
    <item android:id="@+id/action_search"
        android:title="@string/search"
        android:icon="@drawable/search"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionViewClass="android.support.v7.widget.SearchView"></item>
</menu>

Custom ActionView

You can add custom action view to app bar. To do that you need to define action view in layout file and set the layout file as value for actionLayout attribute of one of the menu item in menu xml file. This menu item serves as custom action view.

Below custom action view example shows how to create registration view and set it as action view on app par.

android action view custom actionview example

Activity

package com.zoftino.actionview;

import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class CustomActionViewActivity extends AppCompatActivity {

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

        Toolbar myToolbar = (Toolbar) findViewById(R.id.sv_toolbar);
        setSupportActionBar(myToolbar);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.custom_actionview_menu, menu);

        MenuItem mnItem = menu.findItem(R.id.action_custom);
        View actionView =
                MenuItemCompat.getActionView(mnItem);

        final Button regbutton = (Button) actionView.findViewById(R.id.register);
        regbutton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Toast toast = Toast.makeText(CustomActionViewActivity.this, "Registration complete", Toast.LENGTH_SHORT);
                toast.show();
            }
        });

        return super.onCreateOptionsMenu(menu);
    }
}

custom_actionview_menu.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_settings" android:icon="@drawable/settings" android:title="@string/settings" app:showAsAction="never"></item>
    <item android:id="@+id/action_custom"
        android:title="@string/custom"
        android:icon="@drawable/account"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionLayout="@layout/custom_action_view"></item>
</menu>

custom_action_view.xml

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

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress"
        android:ems="10"
        android:id="@+id/emailAdd"
        android:layout_weight="1"></EditText>

    <Button
        android:text="Register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:id="@+id/register"
        android:layout_weight="1"></Button>
</LinearLayout>