Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 961dd118 authored by Adam Powell's avatar Adam Powell
Browse files

Update ActionProvider to support dynamically building submenus.

Stub out ShareActionProvider for building a submenu of activities to
choose from.

Change-Id: Ibd9ada77a455ed1a296c87b6d967073ca0f676c2
parent ad3f935c
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -20904,8 +20904,10 @@ package android.view {
  public abstract class ActionProvider {
    ctor public ActionProvider(android.content.Context);
    method public boolean hasSubMenu();
    method public abstract android.view.View onCreateActionView();
    method public void onPerformDefaultAction(android.view.View);
    method public boolean onPerformDefaultAction();
    method public void onPrepareSubMenu(android.view.SubMenu);
  }
  public abstract interface ContextMenu implements android.view.Menu {
+29 −4
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ public abstract class ActionProvider {
     * Performs an optional default action.
     * <p>
     * For the case of an action provider placed in a menu item not shown as an action this
     * method is invoked if none of the callbacks for processing menu selection has handled
     * method is invoked if previous callbacks for processing menu selection has handled
     * the event.
     * </p>
     * <p>
@@ -104,11 +104,36 @@ public abstract class ActionProvider {
     * </ul>
     * </p>
     * <p>
     * The default implementation does not perform any action.
     * The default implementation does not perform any action and returns false.
     * </p>
     */
    public boolean onPerformDefaultAction() {
        return false;
    }

    /**
     * Determines if this ActionProvider has a submenu associated with it.
     *
     * <p>Associated submenus will be shown when an action view is not. This
     * provider instance will receive a call to {@link #onPrepareSubMenu(SubMenu)}
     * after the call to {@link #onPerformDefaultAction()} and before a submenu is
     * displayed to the user.
     *
     * @return true if the item backed by this provider should have an associated submenu
     */
    public boolean hasSubMenu() {
        return false;
    }

    /**
     * Called to prepare an associated submenu for the menu item backed by this ActionProvider.
     *
     * <p>if {@link #hasSubMenu()} returns true, this method will be called when the
     * menu item is selected to prepare the submenu for presentation to the user. Apps
     * may use this to create or alter submenu content right before display.
     *
     * @param actionView A view created by {@link #onCreateActionView()}.
     * @param subMenu Submenu that will be displayed
     */
    public void onPerformDefaultAction(View actionView) {
    public void onPrepareSubMenu(SubMenu subMenu) {
    }
}
+23 −11
Original line number Diff line number Diff line
@@ -166,8 +166,13 @@ public class MenuInflater {
                        // Add the item if it hasn't been added (if the item was
                        // a submenu, it would have been added already)
                        if (!menuState.hasAddedItem()) {
                            if (menuState.itemActionProvider != null &&
                                    menuState.itemActionProvider.hasSubMenu()) {
                                menuState.addSubMenuItem();
                            } else {
                                menuState.addItem();
                            }
                        }
                    } else if (tagName.equals(XML_MENU)) {
                        reachedEndOfMenu = true;
                    }
@@ -270,6 +275,8 @@ public class MenuInflater {

        private String itemListenerMethodName;
        
        private ActionProvider itemActionProvider;

        private static final int defaultGroupId = NO_ID;
        private static final int defaultItemId = NO_ID;
        private static final int defaultItemCategory = 0;
@@ -347,6 +354,19 @@ public class MenuInflater {
            itemActionViewClassName = a.getString(com.android.internal.R.styleable.MenuItem_actionViewClass);
            itemActionProviderClassName = a.getString(com.android.internal.R.styleable.MenuItem_actionProviderClass);

            final boolean hasActionProvider = itemActionProviderClassName != null;
            if (hasActionProvider && itemActionViewLayout == 0 && itemActionViewClassName == null) {
                itemActionProvider = newInstance(itemActionProviderClassName,
                            ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE,
                            mActionProviderConstructorArguments);
            } else {
                if (hasActionProvider) {
                    Log.w(LOG_TAG, "Ignoring attribute 'actionProviderClass'."
                            + " Action view already specified.");
                }
                itemActionProvider = null;
            }

            a.recycle();

            itemAdded = false;
@@ -406,16 +426,8 @@ public class MenuInflater {
                            + " Action view already specified.");
                }
            }
            if (itemActionProviderClassName != null) {
                if (!actionViewSpecified) {
                    ActionProvider actionProvider = newInstance(itemActionProviderClassName,
                            ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE,
                            mActionProviderConstructorArguments);
                    item.setActionProvider(actionProvider);
                } else {
                    Log.w(LOG_TAG, "Ignoring attribute 'itemActionProviderClass'."
                            + " Action view already specified.");
                }
            if (itemActionProvider != null) {
                item.setActionProvider(itemActionProvider);
            }
        }

+10 −12
Original line number Diff line number Diff line
@@ -16,16 +16,17 @@

package android.widget;

import com.android.internal.R;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.ActionProvider;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;

import com.android.internal.R;

/**
 * This is a provider for a share action. It is responsible for creating views
 * that enable data sharing and also to perform a default action for showing
@@ -102,17 +103,14 @@ public class ShareActionProvider extends ActionProvider {
        return activityChooserView;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onPerformDefaultAction(View actionView) {
        if (actionView instanceof ActivityChooserView) {
            ActivityChooserView activityChooserView = (ActivityChooserView) actionView;
            activityChooserView.showPopup();
        } else {
            throw new IllegalArgumentException("actionView not instance of ActivityChooserView");
    public boolean hasSubMenu() {
        return true;
    }

    @Override
    public void onPrepareSubMenu(SubMenu subMenu) {
        // TODO Implement me
    }

    /**
+7 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.SparseArray;
import android.view.ActionProvider;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -807,7 +808,12 @@ public class MenuBuilder implements Menu {
        } else if (item.hasSubMenu()) {
            close(false);

            invoked |= dispatchSubMenuSelected((SubMenuBuilder) item.getSubMenu());
            final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
            final ActionProvider provider = item.getActionProvider();
            if (provider != null && provider.hasSubMenu()) {
                provider.onPrepareSubMenu(subMenu);
            }
            invoked |= dispatchSubMenuSelected(subMenu);
            if (!invoked) close(true);
        } else {
            if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) {
Loading