1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.view;
18
19import android.content.Context;
20
21/**
22 * This class is a mediator for accomplishing a given task, for example sharing a file.
23 * It is responsible for creating a view that performs an action that accomplishes the task.
24 * This class also implements other functions such a performing a default action.
25 * <p>
26 * An ActionProvider can be optionally specified for a {@link MenuItem} and in such a
27 * case it will be responsible for creating the action view that appears in the
28 * {@link android.app.ActionBar} as a substitute for the menu item when the item is
29 * displayed as an action item. Also the provider is responsible for performing a
30 * default action if a menu item placed on the overflow menu of the ActionBar is
31 * selected and none of the menu item callbacks has handled the selection. For this
32 * case the provider can also optionally provide a sub-menu for accomplishing the
33 * task at hand.
34 * </p>
35 * <p>
36 * There are two ways for using an action provider for creating and handling of action views:
37 * <ul>
38 * <li>
39 * Setting the action provider on a {@link MenuItem} directly by calling
40 * {@link MenuItem#setActionProvider(ActionProvider)}.
41 * </li>
42 * <li>
43 * Declaring the action provider in the menu XML resource. For example:
44 * <pre>
45 * <code>
46 *   &lt;item android:id="@+id/my_menu_item"
47 *     android:title="Title"
48 *     android:icon="@drawable/my_menu_item_icon"
49 *     android:showAsAction="ifRoom"
50 *     android:actionProviderClass="foo.bar.SomeActionProvider" /&gt;
51 * </code>
52 * </pre>
53 * </li>
54 * </ul>
55 * </p>
56 *
57 * @see MenuItem#setActionProvider(ActionProvider)
58 * @see MenuItem#getActionProvider()
59 */
60public abstract class ActionProvider {
61    private SubUiVisibilityListener mSubUiVisibilityListener;
62
63    /**
64     * Creates a new instance.
65     *
66     * @param context Context for accessing resources.
67     */
68    public ActionProvider(Context context) {
69    }
70
71    /**
72     * Factory method for creating new action views.
73     *
74     * @return A new action view.
75     */
76    public abstract View onCreateActionView();
77
78    /**
79     * Performs an optional default action.
80     * <p>
81     * For the case of an action provider placed in a menu item not shown as an action this
82     * method is invoked if previous callbacks for processing menu selection has handled
83     * the event.
84     * </p>
85     * <p>
86     * A menu item selection is processed in the following order:
87     * <ul>
88     * <li>
89     * Receiving a call to {@link MenuItem.OnMenuItemClickListener#onMenuItemClick
90     *  MenuItem.OnMenuItemClickListener.onMenuItemClick}.
91     * </li>
92     * <li>
93     * Receiving a call to {@link android.app.Activity#onOptionsItemSelected(MenuItem)
94     *  Activity.onOptionsItemSelected(MenuItem)}
95     * </li>
96     * <li>
97     * Receiving a call to {@link android.app.Fragment#onOptionsItemSelected(MenuItem)
98     *  Fragment.onOptionsItemSelected(MenuItem)}
99     * </li>
100     * <li>
101     * Launching the {@link android.content.Intent} set via
102     * {@link MenuItem#setIntent(android.content.Intent) MenuItem.setIntent(android.content.Intent)}
103     * </li>
104     * <li>
105     * Invoking this method.
106     * </li>
107     * </ul>
108     * </p>
109     * <p>
110     * The default implementation does not perform any action and returns false.
111     * </p>
112     */
113    public boolean onPerformDefaultAction() {
114        return false;
115    }
116
117    /**
118     * Determines if this ActionProvider has a submenu associated with it.
119     *
120     * <p>Associated submenus will be shown when an action view is not. This
121     * provider instance will receive a call to {@link #onPrepareSubMenu(SubMenu)}
122     * after the call to {@link #onPerformDefaultAction()} and before a submenu is
123     * displayed to the user.
124     *
125     * @return true if the item backed by this provider should have an associated submenu
126     */
127    public boolean hasSubMenu() {
128        return false;
129    }
130
131    /**
132     * Called to prepare an associated submenu for the menu item backed by this ActionProvider.
133     *
134     * <p>if {@link #hasSubMenu()} returns true, this method will be called when the
135     * menu item is selected to prepare the submenu for presentation to the user. Apps
136     * may use this to create or alter submenu content right before display.
137     *
138     * @param subMenu Submenu that will be displayed
139     */
140    public void onPrepareSubMenu(SubMenu subMenu) {
141    }
142
143    /**
144     * Notify the system that the visibility of an action view's sub-UI such as
145     * an anchored popup has changed. This will affect how other system
146     * visibility notifications occur.
147     *
148     * @hide Pending future API approval
149     */
150    public void subUiVisibilityChanged(boolean isVisible) {
151        if (mSubUiVisibilityListener != null) {
152            mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible);
153        }
154    }
155
156    /**
157     * @hide Internal use only
158     */
159    public void setSubUiVisibilityListener(SubUiVisibilityListener listener) {
160        mSubUiVisibilityListener = listener;
161    }
162
163    /**
164     * @hide Internal use only
165     */
166    public interface SubUiVisibilityListener {
167        public void onSubUiVisibilityChanged(boolean isVisible);
168    }
169}
170