Android UI How to - Create PopupMenu to display just below TextView








The following code shows how to Create PopupMenu to display just below TextView.

Example

Layout activity_main.xml file

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView
        android:id="@+id/anchor"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Menu Will Show Here" />        
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="Show Menu"
        android:onClick="onShowMenuClick"/>
</RelativeLayout>

Menu xml file

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_add"
        android:title="Add Item"
        android:icon="@android:drawable/ic_menu_add"
        android:showAsAction="always|collapseActionView"
        android:actionLayout="@layout/activity_main" />
    <item android:id="@+id/menu_remove"
        android:title="Remove Item"
        android:icon="@android:drawable/ic_menu_delete"
        android:showAsAction="ifRoom" />
    <item android:id="@+id/menu_edit"
        android:title="Edit Item"
        android:icon="@android:drawable/ic_menu_edit"
        android:showAsAction="ifRoom" />
    <item android:id="@+id/menu_settings"
        android:title="Settings"
        android:icon="@android:drawable/ic_menu_preferences"
        android:showAsAction="never" />
</menu>

Main activity Java code

package com.java2s.myapplication3.app;
//from   www . java  2 s  . c o  m
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.PopupMenu;

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class OptionsActivity extends Activity implements
        PopupMenu.OnMenuItemClickListener,
        CompoundButton.OnCheckedChangeListener {

    private MenuItem mOptionsItem;
    private CheckBox mFirstOption, mSecondOption;

    private PopupMenu mPopup;

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

        //Create a PopupMenu to display just below our TextView
        mPopup = new PopupMenu(this, findViewById(R.id.anchor));
        mPopup.setOnMenuItemClickListener(this);
        //Use the same options menu as our Activity
        mPopup.inflate(R.menu.main);
    }

    public void onShowMenuClick(View v) {
        mPopup.show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //Use this callback to create the menu and do any
        // initial setup necessary
        getMenuInflater().inflate(R.menu.main, menu);

        //Find and initialize our action item
        mOptionsItem = menu.findItem(R.id.menu_add);
        mOptionsItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionExpand(
                    MenuItem item) {
                // Must return true to have item expand
                return true;
            }

            @Override
            public boolean onMenuItemActionCollapse(
                    MenuItem item) {
                mFirstOption.setChecked(false);
                mSecondOption.setChecked(false);
                // Must return true to have item collapse
                return true;
            }
        });

        mFirstOption = (CheckBox) mOptionsItem
                .getActionView()
                .findViewById(R.id.menu_add);
        mFirstOption
                .setOnCheckedChangeListener(this);
        mSecondOption = (CheckBox) mOptionsItem
                .getActionView()
                .findViewById(R.id.menu_remove);
        mSecondOption
                .setOnCheckedChangeListener(this);

        return true;
    }

    /* CheckBox Callback Methods */

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (mFirstOption.isChecked() && mSecondOption.isChecked()) {
            mOptionsItem.collapseActionView();
        }
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        //Use this callback to do setup that needs to happen
        // each time the menu opens
        return super.onPrepareOptionsMenu(menu);
    }

    //Callback from the PopupMenu click
    public boolean onMenuItemClick(MenuItem item) {
        menuItemSelected(item);
        return true;
    }

    //Callback from a standard options menu click
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        menuItemSelected(item);
        return true;
    }

    //Private helper so each unique callback can trigger the same actions
    private void menuItemSelected(MenuItem item) {
        //Get the selected option by id
        switch (item.getItemId()) {
            case R.id.menu_add:
                //Do add action
                break;
            case R.id.menu_remove:
                //Do remove action
                break;
            case R.id.menu_edit:
                //Do edit action
                break;
            case R.id.menu_settings:
                //Do settings action
                break;
            default:
                break;
        }
    }
}