diff options
-rw-r--r-- | api/current.xml | 57 | ||||
-rw-r--r-- | core/java/android/app/ActionBar.java | 48 | ||||
-rw-r--r-- | core/java/android/app/Activity.java | 9 | ||||
-rw-r--r-- | core/java/android/app/Dialog.java | 6 | ||||
-rw-r--r-- | core/java/com/android/internal/app/ActionBarImpl.java | 32 | ||||
-rw-r--r-- | core/java/com/android/internal/view/StandaloneActionMode.java | 2 | ||||
-rw-r--r-- | core/java/com/android/internal/view/menu/ActionMenuView.java | 76 | ||||
-rw-r--r-- | core/java/com/android/internal/view/menu/MenuPopupHelper.java | 16 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/ActionBarContextView.java | 6 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/ActionBarView.java | 19 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/actionbar.jd | 22 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindow.java | 84 |
12 files changed, 313 insertions, 64 deletions
diff --git a/api/current.xml b/api/current.xml index e7d5ff4..9fc6e3e 100644 --- a/api/current.xml +++ b/api/current.xml @@ -20749,6 +20749,19 @@ visibility="public" > </constructor> +<method name="addOnMenuVisibilityListener" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="listener" type="android.app.ActionBar.OnMenuVisibilityListener"> +</parameter> +</method> <method name="addTab" return="void" abstract="true" @@ -20998,6 +21011,19 @@ visibility="public" > </method> +<method name="removeOnMenuVisibilityListener" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="listener" type="android.app.ActionBar.OnMenuVisibilityListener"> +</parameter> +</method> <method name="removeTab" return="void" abstract="true" @@ -21131,7 +21157,7 @@ > <parameter name="adapter" type="android.widget.SpinnerAdapter"> </parameter> -<parameter name="callback" type="android.app.ActionBar.NavigationCallback"> +<parameter name="callback" type="android.app.ActionBar.OnNavigationListener"> </parameter> </method> <method name="setDropdownNavigationMode" @@ -21146,7 +21172,7 @@ > <parameter name="adapter" type="android.widget.SpinnerAdapter"> </parameter> -<parameter name="callback" type="android.app.ActionBar.NavigationCallback"> +<parameter name="callback" type="android.app.ActionBar.OnNavigationListener"> </parameter> <parameter name="defaultSelectedPosition" type="int"> </parameter> @@ -21163,7 +21189,7 @@ > <parameter name="adapter" type="android.widget.SpinnerAdapter"> </parameter> -<parameter name="callback" type="android.app.ActionBar.NavigationCallback"> +<parameter name="callback" type="android.app.ActionBar.OnNavigationListener"> </parameter> </method> <method name="setNavigationMode" @@ -21475,7 +21501,28 @@ > </field> </class> -<interface name="ActionBar.NavigationCallback" +<interface name="ActionBar.OnMenuVisibilityListener" + abstract="true" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<method name="onMenuVisibilityChanged" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="isVisible" type="boolean"> +</parameter> +</method> +</interface> +<interface name="ActionBar.OnNavigationListener" abstract="true" static="true" final="false" @@ -249389,7 +249436,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="t" type="T"> +<parameter name="arg0" type="T"> </parameter> </method> </interface> diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index 7a6ad0f..2f69520 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -168,13 +168,13 @@ public abstract class ActionBar { * @param adapter An adapter that will provide views both to display * the current navigation selection and populate views * within the dropdown navigation menu. - * @param callback A NavigationCallback that will receive events when the user + * @param callback A OnNavigationListener that will receive events when the user * selects a navigation item. * @deprecated See setListNavigationCallbacks. */ @Deprecated public abstract void setDropdownNavigationMode(SpinnerAdapter adapter, - NavigationCallback callback); + OnNavigationListener callback); /** * Set the adapter and navigation callback for list navigation mode. @@ -182,17 +182,17 @@ public abstract class ActionBar { * The supplied adapter will provide views for the expanded list as well as * the currently selected item. (These may be displayed differently.) * - * The supplied NavigationCallback will alert the application when the user + * The supplied OnNavigationListener will alert the application when the user * changes the current list selection. * * @param adapter An adapter that will provide views both to display * the current navigation selection and populate views * within the dropdown navigation menu. - * @param callback A NavigationCallback that will receive events when the user + * @param callback An OnNavigationListener that will receive events when the user * selects a navigation item. */ public abstract void setListNavigationCallbacks(SpinnerAdapter adapter, - NavigationCallback callback); + OnNavigationListener callback); /** * Set the action bar into dropdown navigation mode and supply an adapter that will @@ -201,7 +201,7 @@ public abstract class ActionBar { * @param adapter An adapter that will provide views both to display the current * navigation selection and populate views within the dropdown * navigation menu. - * @param callback A NavigationCallback that will receive events when the user + * @param callback A OnNavigationListener that will receive events when the user * selects a navigation item. * @param defaultSelectedPosition Position within the provided adapter that should be * selected from the outset. @@ -209,7 +209,7 @@ public abstract class ActionBar { */ @Deprecated public abstract void setDropdownNavigationMode(SpinnerAdapter adapter, - NavigationCallback callback, int defaultSelectedPosition); + OnNavigationListener callback, int defaultSelectedPosition); /** * Set the selected navigation item in list or tabbed navigation modes. @@ -532,9 +532,24 @@ public abstract class ActionBar { public abstract boolean isShowing(); /** - * Callback interface for ActionBar navigation events. + * Add a listener that will respond to menu visibility change events. + * + * @param listener The new listener to add + */ + public abstract void addOnMenuVisibilityListener(OnMenuVisibilityListener listener); + + /** + * Remove a menu visibility listener. This listener will no longer receive menu + * visibility change events. + * + * @param listener A listener to remove that was previously added + */ + public abstract void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener); + + /** + * Listener interface for ActionBar navigation events. */ - public interface NavigationCallback { + public interface OnNavigationListener { /** * This method is called whenever a navigation item in your action bar * is selected. @@ -547,6 +562,21 @@ public abstract class ActionBar { } /** + * Listener for receiving events when action bar menus are shown or hidden. + */ + public interface OnMenuVisibilityListener { + /** + * Called when an action bar menu is shown or hidden. Applications may want to use + * this to tune auto-hiding behavior for the action bar or pause/resume video playback, + * gameplay, or other activity within the main content area. + * + * @param isVisible True if an action bar menu is now visible, false if no action bar + * menus are visible. + */ + public void onMenuVisibilityChanged(boolean isVisible); + } + + /** * A tab in the action bar. * * <p>Tabs manage the hiding and showing of {@link Fragment}s. diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index d69a179..6b619fb 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -2362,6 +2362,9 @@ public class Activity extends ContextThemeWrapper * @return The default implementation returns true. */ public boolean onMenuOpened(int featureId, Menu menu) { + if (featureId == Window.FEATURE_ACTION_BAR) { + mActionBar.dispatchMenuVisibilityChanged(true); + } return true; } @@ -2392,7 +2395,7 @@ public class Activity extends ContextThemeWrapper return true; } return mFragments.dispatchContextItemSelected(item); - + default: return false; } @@ -2417,6 +2420,10 @@ public class Activity extends ContextThemeWrapper case Window.FEATURE_CONTEXT_MENU: onContextMenuClosed(menu); break; + + case Window.FEATURE_ACTION_BAR: + mActionBar.dispatchMenuVisibilityChanged(false); + break; } } diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index 64a4d7a..f90fc59 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -735,6 +735,9 @@ public class Dialog implements DialogInterface, Window.Callback, * @see Activity#onMenuOpened(int, Menu) */ public boolean onMenuOpened(int featureId, Menu menu) { + if (featureId == Window.FEATURE_ACTION_BAR) { + mActionBar.dispatchMenuVisibilityChanged(true); + } return true; } @@ -749,6 +752,9 @@ public class Dialog implements DialogInterface, Window.Callback, * @see Activity#onPanelClosed(int, Menu) */ public void onPanelClosed(int featureId, Menu menu) { + if (featureId == Window.FEATURE_ACTION_BAR) { + mActionBar.dispatchMenuVisibilityChanged(false); + } } /** diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index 20402a3..447a062 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -70,6 +70,10 @@ public class ActionBarImpl extends ActionBar { private ActionMode mActionMode; + private boolean mLastMenuVisibility; + private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners = + new ArrayList<OnMenuVisibilityListener>(); + private static final int CONTEXT_DISPLAY_NORMAL = 0; private static final int CONTEXT_DISPLAY_SPLIT = 1; @@ -120,6 +124,26 @@ public class ActionBarImpl extends ActionBar { CONTEXT_DISPLAY_NORMAL : CONTEXT_DISPLAY_SPLIT; } + public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) { + mMenuVisibilityListeners.add(listener); + } + + public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) { + mMenuVisibilityListeners.remove(listener); + } + + public void dispatchMenuVisibilityChanged(boolean isVisible) { + if (isVisible == mLastMenuVisibility) { + return; + } + mLastMenuVisibility = isVisible; + + final int count = mMenuVisibilityListeners.size(); + for (int i = 0; i < count; i++) { + mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible); + } + } + @Override public void setTitle(int resId) { setTitle(mContext.getString(resId)); @@ -138,11 +162,11 @@ public class ActionBarImpl extends ActionBar { mActionView.setCallback(null); } - public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback) { + public void setDropdownNavigationMode(SpinnerAdapter adapter, OnNavigationListener callback) { setDropdownNavigationMode(adapter, callback, -1); } - public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback, + public void setDropdownNavigationMode(SpinnerAdapter adapter, OnNavigationListener callback, int defaultSelectedPosition) { cleanupTabs(); setDisplayOptions(0, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE); @@ -516,7 +540,7 @@ public class ActionBarImpl extends ActionBar { public void onMenuModeChange(MenuBuilder menu) { invalidate(); - mUpperContextView.showOverflowMenu(); + mUpperContextView.openOverflowMenu(); } } @@ -627,7 +651,7 @@ public class ActionBarImpl extends ActionBar { } @Override - public void setListNavigationCallbacks(SpinnerAdapter adapter, NavigationCallback callback) { + public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) { mActionView.setDropdownAdapter(adapter); mActionView.setCallback(callback); } diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java index b54daba..2d067da 100644 --- a/core/java/com/android/internal/view/StandaloneActionMode.java +++ b/core/java/com/android/internal/view/StandaloneActionMode.java @@ -135,6 +135,6 @@ public class StandaloneActionMode extends ActionMode implements MenuBuilder.Call public void onMenuModeChange(MenuBuilder menu) { invalidate(); - mContextView.showOverflowMenu(); + mContextView.openOverflowMenu(); } } diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java index 621defe..84067d0 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuView.java @@ -59,6 +59,22 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } }; + private class OpenOverflowRunnable implements Runnable { + private MenuPopupHelper mPopup; + + public OpenOverflowRunnable(MenuPopupHelper popup) { + mPopup = popup; + } + + public void run() { + mOverflowPopup = mPopup; + mPopup.show(); + mPostedOpenRunnable = null; + } + } + + private OpenOverflowRunnable mPostedOpenRunnable; + public ActionMenuView(Context context) { this(context, null); } @@ -100,6 +116,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo @Override public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); final int screen = newConfig.screenLayout; mReserveOverflow = (screen & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE; @@ -115,6 +132,14 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } } + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mOverflowPopup != null && mOverflowPopup.isShowing()) { + mOverflowPopup.dismiss(); + } + } + private int getMaxActionButtons() { return getResources().getInteger(com.android.internal.R.integer.max_action_buttons); } @@ -193,30 +218,34 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } public boolean showOverflowMenu() { - if (mOverflowButton != null) { - final MenuPopupHelper popup = - new MenuPopupHelper(getContext(), mMenu, mOverflowButton, true); - // Post this for later; we might still need a layout for the anchor to be right. - post(new Runnable() { - public void run() { - popup.show(); - } - }); - mOverflowPopup = popup; + if (mOverflowButton != null && !isOverflowMenuShowing()) { + mMenu.getCallback().onMenuModeChange(mMenu); return true; } return false; } + public void openOverflowMenu() { + OverflowPopup popup = new OverflowPopup(getContext(), mMenu, mOverflowButton, true); + mPostedOpenRunnable = new OpenOverflowRunnable(popup); + // Post this for later; we might still need a layout for the anchor to be right. + post(mPostedOpenRunnable); + } + public boolean isOverflowMenuShowing() { - MenuPopupHelper popup = mOverflowPopup; - if (popup != null) { - return popup.isShowing(); - } - return false; + return mOverflowPopup != null && mOverflowPopup.isShowing(); + } + + public boolean isOverflowMenuOpen() { + return mOverflowPopup != null; } public boolean hideOverflowMenu() { + if (mPostedOpenRunnable != null) { + removeCallbacks(mPostedOpenRunnable); + return true; + } + MenuPopupHelper popup = mOverflowPopup; if (popup != null) { popup.dismiss(); @@ -274,9 +303,22 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo return true; } - // Change to overflow mode - mMenu.getCallback().onMenuModeChange(mMenu); + showOverflowMenu(); return true; } } + + private class OverflowPopup extends MenuPopupHelper { + public OverflowPopup(Context context, MenuBuilder menu, View anchorView, + boolean overflowOnly) { + super(context, menu, anchorView, overflowOnly); + } + + @Override + public void onDismiss() { + super.onDismiss(); + mMenu.getCallback().onCloseMenu(mMenu, true); + mOverflowPopup = null; + } + } } diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java index 1406e4e..2cb78a5 100644 --- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java +++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java @@ -35,7 +35,7 @@ import java.lang.ref.WeakReference; * @hide */ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener, - ViewTreeObserver.OnGlobalLayoutListener { + ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener { private static final String TAG = "MenuPopupHelper"; private Context mContext; @@ -46,12 +46,6 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On private boolean mOverflowOnly; private ViewTreeObserver mTreeObserver; - private PopupWindow.OnDismissListener mDismissListener = new PopupWindow.OnDismissListener() { - public void onDismiss() { - mPopup = null; - } - }; - public MenuPopupHelper(Context context, MenuBuilder menu) { this(context, menu, null, false); } @@ -77,7 +71,7 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On public void show() { mPopup = new ListPopupWindow(mContext, null, com.android.internal.R.attr.popupMenuStyle); mPopup.setOnItemClickListener(this); - mPopup.setOnDismissListener(mDismissListener); + mPopup.setOnDismissListener(this); final MenuAdapter adapter = mOverflowOnly ? mMenu.getOverflowMenuAdapter(MenuBuilder.TYPE_POPUP) : @@ -110,8 +104,12 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On if (isShowing()) { mPopup.dismiss(); } + } + + public void onDismiss() { + mPopup = null; if (mTreeObserver != null) { - mTreeObserver.removeGlobalOnLayoutListener(this); + mTreeObserver.removeGlobalOnLayoutListener(MenuPopupHelper.this); mTreeObserver = null; } } diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index e93c414..cbf12bf 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -180,6 +180,12 @@ public class ActionBarContextView extends ViewGroup { return false; } + public void openOverflowMenu() { + if (mMenuView != null) { + mMenuView.openOverflowMenu(); + } + } + public boolean hideOverflowMenu() { if (mMenuView != null) { return mMenuView.hideOverflowMenu(); diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index f931217..07a65fc 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -22,7 +22,7 @@ import com.android.internal.view.menu.ActionMenuView; import com.android.internal.view.menu.MenuBuilder; import android.app.ActionBar; -import android.app.ActionBar.NavigationCallback; +import android.app.ActionBar.OnNavigationListener; import android.app.Activity; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -114,7 +114,7 @@ public class ActionBarView extends ViewGroup { private ActionMenuItem mLogoNavItem; private SpinnerAdapter mSpinnerAdapter; - private NavigationCallback mCallback; + private OnNavigationListener mCallback; private final AdapterView.OnItemSelectedListener mNavItemSelectedListener = new AdapterView.OnItemSelectedListener() { @@ -243,7 +243,7 @@ public class ActionBarView extends ViewGroup { return null; } - public void setCallback(NavigationCallback callback) { + public void setCallback(OnNavigationListener callback) { mCallback = callback; } @@ -269,6 +269,12 @@ public class ActionBarView extends ViewGroup { return false; } + public void openOverflowMenu() { + if (mMenuView != null) { + mMenuView.openOverflowMenu(); + } + } + public void postShowOverflowMenu() { post(new Runnable() { public void run() { @@ -291,6 +297,13 @@ public class ActionBarView extends ViewGroup { return false; } + public boolean isOverflowMenuOpen() { + if (mMenuView != null) { + return mMenuView.isOverflowMenuOpen(); + } + return false; + } + public boolean isOverflowReserved() { return mMenuView != null && mMenuView.isOverflowReserved(); } diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd index c3d3482..44d75c1 100644 --- a/docs/html/guide/topics/ui/actionbar.jd +++ b/docs/html/guide/topics/ui/actionbar.jd @@ -455,7 +455,7 @@ Action Bar.</p> <ol> <li>Create a {@link android.widget.SpinnerAdapter} that provides the list of selectable items for the list and the layout to use when drawing each item in the list.</li> - <li>Implement {@link android.app.ActionBar.NavigationCallback} to define the behavior when the + <li>Implement {@link android.app.ActionBar.OnNavigationListener} to define the behavior when the user selects an item from the list.</li> <li>Turn on navigation mode for the Action Bar with {@link android.app.ActionBar#setNavigationMode setNavigationMode()}. For example: @@ -472,17 +472,17 @@ android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}. actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback); </pre> <p>This method takes your {@link android.widget.SpinnerAdapter} and {@link -android.app.ActionBar.NavigationCallback}. More about these next.</p> +android.app.ActionBar.OnNavigationListener}. More about these next.</p> </li> </ol> <p>That's the basic setup. The {@link android.widget.SpinnerAdapter} and {@link -android.app.ActionBar.NavigationCallback} is where most of the work is done. There are many ways +android.app.ActionBar.OnNavigationListener} is where most of the work is done. There are many ways you can implement these to define the functionality for your drop-down navigation. Implementing various types of {@link android.widget.SpinnerAdapter} is beyond the scope of this document—you should refer to the class refrence for more information about implementing it or extending an existing implementation. However, below is a simple example for a {@link -android.widget.SpinnerAdapter} and {@link android.app.ActionBar.NavigationCallback} to get you +android.widget.SpinnerAdapter} and {@link android.app.ActionBar.OnNavigationListener} to get you started.</p> @@ -520,24 +520,24 @@ defined as a resource looks like this:</p> </pre> -<h3 id="NavigationCallback">Example: simple NavigationCallback</h3> +<h3 id="OnNavigationListener">Example: simple OnNavigationListener</h3> -<p>Your implementation of {@link android.app.ActionBar.NavigationCallback} is where you handle +<p>Your implementation of {@link android.app.ActionBar.OnNavigationListener} is where you handle fragment changes or other modifications to your activity when the user selects an item from the drop-down list. There's only one callback method to implement: {@link -android.app.ActionBar.NavigationCallback#onNavigationItemSelected onNavigationItemSelected()}.</p> +android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}.</p> <p>The {@link -android.app.ActionBar.NavigationCallback#onNavigationItemSelected onNavigationItemSelected()} +android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()} method receives the position of the item in the list and an item ID provided by the {@link android.widget.SpinnerAdapter}.</p> <p>Here's an example that instantiates an anonymous implementation of {@link -android.app.ActionBar.NavigationCallback}, which inserts a {@link android.app.Fragment} into the +android.app.ActionBar.OnNavigationListener}, which inserts a {@link android.app.Fragment} into the layout container identified by {@code R.id.fragment_container}:</p> <pre> -mNavigationCallback = new NavigationCallback() { +mOnNavigationListener = new OnNavigationListener() { // Get the same strings provided for the drop-down's ArrayAdapter String[] strings = getResources().getStringArray(R.array.action_list); @@ -556,7 +556,7 @@ mNavigationCallback = new NavigationCallback() { }; </pre> -<p>This instance of {@link android.app.ActionBar.NavigationCallback} can be given to {@link +<p>This instance of {@link android.app.ActionBar.OnNavigationListener} can be given to {@link android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}, in step 4 from above.</p> diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index cd8a065..138dff7 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -160,6 +160,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private ContextMenuBuilder mContextMenu; private MenuDialogHelper mContextMenuHelper; + private ActionButtonSubmenu mActionButtonPopup; + private boolean mClosingActionMenu; private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE; @@ -542,6 +544,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (doCallback) { callOnPanelClosed(st.featureId, st, null); } + } else if (st.featureId == FEATURE_OPTIONS_PANEL && doCallback && + mActionBar != null) { + checkCloseActionMenu(st.menu); } st.isPrepared = false; st.isHandled = false; @@ -563,6 +568,27 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } } + private void checkCloseActionMenu(Menu menu) { + if (mClosingActionMenu) { + return; + } + + boolean closed = false; + mClosingActionMenu = true; + if (mActionBar.isOverflowMenuOpen() && mActionBar.hideOverflowMenu()) { + closed = true; + } + if (mActionButtonPopup != null) { + mActionButtonPopup.dismiss(); + closed = true; + } + Callback cb = getCallback(); + if (cb != null && closed) { + cb.onPanelClosed(FEATURE_ACTION_BAR, menu); + } + mClosingActionMenu = false; + } + @Override public final void togglePanel(int featureId, KeyEvent event) { PanelFeatureState st = getPanelState(featureId, true); @@ -842,7 +868,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { // The window manager will give us a valid window token new MenuDialogHelper(subMenu).show(null); } else { - new MenuPopupHelper(getContext(), subMenu).show(); + mActionButtonPopup = new ActionButtonSubmenu(getContext(), subMenu); + mActionButtonPopup.show(); + Callback cb = getCallback(); + if (cb != null) { + cb.onMenuOpened(FEATURE_ACTION_BAR, subMenu); + } } return true; @@ -854,16 +885,21 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private void reopenMenu(boolean toggleMenuMode) { if (mActionBar != null) { + final Callback cb = getCallback(); if (!mActionBar.isOverflowMenuShowing() || !toggleMenuMode) { - final Callback cb = getCallback(); if (cb != null) { final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); if (cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) { - mActionBar.showOverflowMenu(); + cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu); + mActionBar.openOverflowMenu(); } } } else { mActionBar.hideOverflowMenu(); + if (cb != null) { + final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); + cb.onPanelClosed(FEATURE_ACTION_BAR, st.menu); + } } return; } @@ -2042,8 +2078,23 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (cb != null && mFeatureId < 0) { cb.onDetachedFromWindow(); } + + if (mActionButtonPopup != null) { + if (mActionButtonPopup.isShowing()) { + mActionButtonPopup.dismiss(); + } + mActionButtonPopup = null; + } } - + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + if (mActionButtonPopup != null) { + mActionButtonPopup.dismiss(); + post(mActionButtonPopup); + } + } + @Override public void onCloseSystemDialogs(String reason) { if (mFeatureId >= 0) { @@ -2921,4 +2972,29 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { void sendCloseSystemWindows(String reason) { PhoneWindowManager.sendCloseSystemWindows(getContext(), reason); } + + private class ActionButtonSubmenu extends MenuPopupHelper implements Runnable { + private SubMenuBuilder mSubMenu; + + public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { + super(context, subMenu); + mSubMenu = subMenu; + } + + @Override + public void onDismiss() { + super.onDismiss(); + mSubMenu.getCallback().onCloseSubMenu(mSubMenu); + mActionButtonPopup = null; + } + + @Override + public void run() { + show(); + Callback cb = getCallback(); + if (cb != null) { + cb.onMenuOpened(FEATURE_ACTION_BAR, mSubMenu); + } + } + } } |