ActionMenuView.java revision 3f476b34049d062942eafcf48396f593e00bd324
196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell/* 296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * Copyright (C) 2010 The Android Open Source Project 396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * 496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * you may not use this file except in compliance with the License. 696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * You may obtain a copy of the License at 796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * 896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * http://www.apache.org/licenses/LICENSE-2.0 996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * 1096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * Unless required by applicable law or agreed to in writing, software 1196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * distributed under the License is distributed on an "AS IS" BASIS, 1296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * See the License for the specific language governing permissions and 1496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * limitations under the License. 1596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell */ 1696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellpackage com.android.internal.view.menu; 1796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 1896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellimport android.content.Context; 198028dd32a4a04154050220dd0693583d5b750330Adam Powellimport android.content.res.Configuration; 207ade1be822ed05a143b059319dccd5e9f623b56dAdam Powellimport android.content.res.Resources; 217ade1be822ed05a143b059319dccd5e9f623b56dAdam Powellimport android.content.res.TypedArray; 22be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powellimport android.graphics.drawable.Drawable; 2396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellimport android.util.AttributeSet; 246b336f835d637853800b94689375a03f337139a4Adam Powellimport android.view.Gravity; 253f476b34049d062942eafcf48396f593e00bd324Adam Powellimport android.view.LayoutInflater; 26cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powellimport android.view.View; 277ade1be822ed05a143b059319dccd5e9f623b56dAdam Powellimport android.view.ViewGroup; 289ab978713ce86fdaefed2407f4f3c998ab0e3178Adam Powellimport android.view.ViewParent; 298028dd32a4a04154050220dd0693583d5b750330Adam Powellimport android.widget.ImageButton; 30be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powellimport android.widget.ImageView; 3196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellimport android.widget.LinearLayout; 3296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 3396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellimport java.util.ArrayList; 3496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 3596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell/** 3696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * @hide 3796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell */ 3896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellpublic class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvoker, MenuView { 3996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell private static final String TAG = "ActionMenuView"; 40be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 41be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell // TODO Theme/style this. 42be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private static final int DIVIDER_PADDING = 12; // dips 4396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 4496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell private MenuBuilder mMenu; 457ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell 467ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell private int mMaxItems; 478028dd32a4a04154050220dd0693583d5b750330Adam Powell private boolean mReserveOverflow; 488028dd32a4a04154050220dd0693583d5b750330Adam Powell private OverflowMenuButton mOverflowButton; 496c6f575423d6718c3ff322224c1520901ce881e1Adam Powell private MenuPopupHelper mOverflowPopup; 50be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 51be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private float mButtonPaddingLeft; 52be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private float mButtonPaddingRight; 53be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private float mDividerPadding; 54be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 55be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private Drawable mDivider; 566c6f575423d6718c3ff322224c1520901ce881e1Adam Powell 576c6f575423d6718c3ff322224c1520901ce881e1Adam Powell private Runnable mShowOverflow = new Runnable() { 586c6f575423d6718c3ff322224c1520901ce881e1Adam Powell public void run() { 596c6f575423d6718c3ff322224c1520901ce881e1Adam Powell showOverflowMenu(); 606c6f575423d6718c3ff322224c1520901ce881e1Adam Powell } 616c6f575423d6718c3ff322224c1520901ce881e1Adam Powell }; 6296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 638515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell private class OpenOverflowRunnable implements Runnable { 648515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell private MenuPopupHelper mPopup; 658515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 668515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell public OpenOverflowRunnable(MenuPopupHelper popup) { 678515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mPopup = popup; 688515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 698515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 708515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell public void run() { 718515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mOverflowPopup = mPopup; 728515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mPopup.show(); 738515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mPostedOpenRunnable = null; 748515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 758515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 768515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 778515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell private OpenOverflowRunnable mPostedOpenRunnable; 788515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 7996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public ActionMenuView(Context context) { 8096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell this(context, null); 8196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 8296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 8396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public ActionMenuView(Context context, AttributeSet attrs) { 8496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell super(context, attrs); 857ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell 86be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell final Resources res = getResources(); 87773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell 88773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell // Measure for initial configuration 89be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell mMaxItems = getMaxActionButtons(); 90773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell 91773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell // TODO There has to be a better way to indicate that we don't have a hard menu key. 92be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell final int screen = res.getConfiguration().screenLayout; 93773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell mReserveOverflow = (screen & Configuration.SCREENLAYOUT_SIZE_MASK) == 94773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell Configuration.SCREENLAYOUT_SIZE_XLARGE; 95be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 96be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell TypedArray a = context.obtainStyledAttributes(com.android.internal.R.styleable.Theme); 97be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell final int buttonStyle = a.getResourceId( 98be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell com.android.internal.R.styleable.Theme_actionButtonStyle, 0); 99cf0357639e952a87f0d535c82691919af81f058bAdam Powell mDivider = a.getDrawable(com.android.internal.R.styleable.Theme_dividerVertical); 100be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell a.recycle(); 101be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 102be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell a = context.obtainStyledAttributes(buttonStyle, com.android.internal.R.styleable.View); 103be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell mButtonPaddingLeft = a.getDimension(com.android.internal.R.styleable.View_paddingLeft, 0); 104be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell mButtonPaddingRight = a.getDimension(com.android.internal.R.styleable.View_paddingRight, 0); 105be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell a.recycle(); 106be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 107be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell mDividerPadding = DIVIDER_PADDING * res.getDisplayMetrics().density; 108f16888f1e849b0bc0b9c17e5f833c4e2cd54c382Adam Powell 109f16888f1e849b0bc0b9c17e5f833c4e2cd54c382Adam Powell setBaselineAligned(false); 110773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell } 111773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell 1126c6f575423d6718c3ff322224c1520901ce881e1Adam Powell @Override 113773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell public void onConfigurationChanged(Configuration newConfig) { 1148515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell super.onConfigurationChanged(newConfig); 115773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell final int screen = newConfig.screenLayout; 116773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell mReserveOverflow = (screen & Configuration.SCREENLAYOUT_SIZE_MASK) == 117773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell Configuration.SCREENLAYOUT_SIZE_XLARGE; 118be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell mMaxItems = getMaxActionButtons(); 119773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell if (mMenu != null) { 120773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell mMenu.setMaxActionItems(mMaxItems); 121773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell updateChildren(false); 122773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell } 1236c6f575423d6718c3ff322224c1520901ce881e1Adam Powell 1246c6f575423d6718c3ff322224c1520901ce881e1Adam Powell if (mOverflowPopup != null && mOverflowPopup.isShowing()) { 1256c6f575423d6718c3ff322224c1520901ce881e1Adam Powell mOverflowPopup.dismiss(); 1266c6f575423d6718c3ff322224c1520901ce881e1Adam Powell post(mShowOverflow); 1276c6f575423d6718c3ff322224c1520901ce881e1Adam Powell } 128773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell } 129773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell 1308515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell @Override 1318515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell public void onDetachedFromWindow() { 1328515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell super.onDetachedFromWindow(); 1338515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell if (mOverflowPopup != null && mOverflowPopup.isShowing()) { 1348515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mOverflowPopup.dismiss(); 1358515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 1368515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 1378515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 138be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private int getMaxActionButtons() { 139be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell return getResources().getInteger(com.android.internal.R.integer.max_action_buttons); 1408028dd32a4a04154050220dd0693583d5b750330Adam Powell } 1418028dd32a4a04154050220dd0693583d5b750330Adam Powell 1428028dd32a4a04154050220dd0693583d5b750330Adam Powell public boolean isOverflowReserved() { 1438028dd32a4a04154050220dd0693583d5b750330Adam Powell return mReserveOverflow; 1447ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell } 1457ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell 146b366bbae2b5a3009893ef64246e3430cea4b7736Adam Powell public void setOverflowReserved(boolean reserveOverflow) { 147b366bbae2b5a3009893ef64246e3430cea4b7736Adam Powell mReserveOverflow = reserveOverflow; 148b366bbae2b5a3009893ef64246e3430cea4b7736Adam Powell } 1497ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell 1507ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell @Override 1517ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell protected LayoutParams generateDefaultLayoutParams() { 1527ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, 1537ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell LayoutParams.WRAP_CONTENT); 1546b336f835d637853800b94689375a03f337139a4Adam Powell params.gravity = Gravity.CENTER_VERTICAL; 1557ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell return params; 1567ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell } 1577ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell 1587ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell @Override 1597ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 1603f476b34049d062942eafcf48396f593e00bd324Adam Powell if (p instanceof LayoutParams) { 1613f476b34049d062942eafcf48396f593e00bd324Adam Powell LayoutParams result = new LayoutParams((LayoutParams) p); 1623f476b34049d062942eafcf48396f593e00bd324Adam Powell if (result.gravity <= Gravity.NO_GRAVITY) { 1633f476b34049d062942eafcf48396f593e00bd324Adam Powell result.gravity = Gravity.CENTER_VERTICAL; 1643f476b34049d062942eafcf48396f593e00bd324Adam Powell } 1653f476b34049d062942eafcf48396f593e00bd324Adam Powell return result; 1663f476b34049d062942eafcf48396f593e00bd324Adam Powell } 1677ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell return generateDefaultLayoutParams(); 1687ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell } 16996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 17096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public boolean invokeItem(MenuItemImpl item) { 17196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell return mMenu.performItemAction(item, 0); 17296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 17396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 17496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public int getWindowAnimations() { 17596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell return 0; 17696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 17796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 17896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public void initialize(MenuBuilder menu, int menuType) { 1797ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell menu.setMaxActionItems(mMaxItems); 18096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell mMenu = menu; 18196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell updateChildren(true); 18296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 18396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 18496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public void updateChildren(boolean cleared) { 1858028dd32a4a04154050220dd0693583d5b750330Adam Powell final boolean reserveOverflow = mReserveOverflow; 18696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell removeAllViews(); 18796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 1888028dd32a4a04154050220dd0693583d5b750330Adam Powell final ArrayList<MenuItemImpl> itemsToShow = mMenu.getActionItems(reserveOverflow); 18996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell final int itemCount = itemsToShow.size(); 19096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 191be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell boolean needsDivider = false; 19296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell for (int i = 0; i < itemCount; i++) { 193be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell if (needsDivider) { 194be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell addView(makeDividerView(), makeDividerLayoutParams()); 195be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell } 19696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell final MenuItemImpl itemData = itemsToShow.get(i); 1973f476b34049d062942eafcf48396f593e00bd324Adam Powell View actionView = itemData.getActionView(); 1983f476b34049d062942eafcf48396f593e00bd324Adam Powell 1993f476b34049d062942eafcf48396f593e00bd324Adam Powell if (actionView == null) { 2003f476b34049d062942eafcf48396f593e00bd324Adam Powell // Check for a layout ID instead 2013f476b34049d062942eafcf48396f593e00bd324Adam Powell final int layoutId = itemData.getActionViewId(); 2023f476b34049d062942eafcf48396f593e00bd324Adam Powell if (layoutId != 0) { 2033f476b34049d062942eafcf48396f593e00bd324Adam Powell LayoutInflater inflater = LayoutInflater.from(getContext()); 2043f476b34049d062942eafcf48396f593e00bd324Adam Powell actionView = inflater.inflate(layoutId, this, false); 2053f476b34049d062942eafcf48396f593e00bd324Adam Powell itemData.setActionView(0); 2063f476b34049d062942eafcf48396f593e00bd324Adam Powell itemData.setActionView(actionView); 2073f476b34049d062942eafcf48396f593e00bd324Adam Powell } 2083f476b34049d062942eafcf48396f593e00bd324Adam Powell } 2093f476b34049d062942eafcf48396f593e00bd324Adam Powell 210cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell if (actionView != null) { 2119ab978713ce86fdaefed2407f4f3c998ab0e3178Adam Powell final ViewParent parent = actionView.getParent(); 2129ab978713ce86fdaefed2407f4f3c998ab0e3178Adam Powell if (parent instanceof ViewGroup) { 2139ab978713ce86fdaefed2407f4f3c998ab0e3178Adam Powell ((ViewGroup) parent).removeView(actionView); 2149ab978713ce86fdaefed2407f4f3c998ab0e3178Adam Powell } 2153f476b34049d062942eafcf48396f593e00bd324Adam Powell addView(actionView, makeActionViewLayoutParams(actionView)); 216cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell } else { 217be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell needsDivider = addItemView(i == 0 || !needsDivider, 218be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell (ActionMenuItemView) itemData.getItemView( 219be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell MenuBuilder.TYPE_ACTION_BUTTON, this)); 220cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powell } 22196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 2228028dd32a4a04154050220dd0693583d5b750330Adam Powell 2238028dd32a4a04154050220dd0693583d5b750330Adam Powell if (reserveOverflow) { 2248028dd32a4a04154050220dd0693583d5b750330Adam Powell if (mMenu.getNonActionItems(true).size() > 0) { 2258028dd32a4a04154050220dd0693583d5b750330Adam Powell OverflowMenuButton button = new OverflowMenuButton(mContext); 2268028dd32a4a04154050220dd0693583d5b750330Adam Powell addView(button); 2278028dd32a4a04154050220dd0693583d5b750330Adam Powell mOverflowButton = button; 2288028dd32a4a04154050220dd0693583d5b750330Adam Powell } else { 2298028dd32a4a04154050220dd0693583d5b750330Adam Powell mOverflowButton = null; 2308028dd32a4a04154050220dd0693583d5b750330Adam Powell } 2318028dd32a4a04154050220dd0693583d5b750330Adam Powell } 2328028dd32a4a04154050220dd0693583d5b750330Adam Powell } 2338028dd32a4a04154050220dd0693583d5b750330Adam Powell 2348028dd32a4a04154050220dd0693583d5b750330Adam Powell public boolean showOverflowMenu() { 2358515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell if (mOverflowButton != null && !isOverflowMenuShowing()) { 2368515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mMenu.getCallback().onMenuModeChange(mMenu); 237f75eeb28def26798682748aa5dedabebac86bb6aAdam Powell return true; 238f75eeb28def26798682748aa5dedabebac86bb6aAdam Powell } 239f75eeb28def26798682748aa5dedabebac86bb6aAdam Powell return false; 240f75eeb28def26798682748aa5dedabebac86bb6aAdam Powell } 241f75eeb28def26798682748aa5dedabebac86bb6aAdam Powell 2428515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell public void openOverflowMenu() { 2438515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell OverflowPopup popup = new OverflowPopup(getContext(), mMenu, mOverflowButton, true); 2448515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mPostedOpenRunnable = new OpenOverflowRunnable(popup); 2458515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell // Post this for later; we might still need a layout for the anchor to be right. 2468515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell post(mPostedOpenRunnable); 2478515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 2488515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 249f6148c53f93978af678cc0559a4417b608a33ae1Adam Powell public boolean isOverflowMenuShowing() { 2508515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell return mOverflowPopup != null && mOverflowPopup.isShowing(); 2518515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 2528515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 2538515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell public boolean isOverflowMenuOpen() { 2548515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell return mOverflowPopup != null; 255f6148c53f93978af678cc0559a4417b608a33ae1Adam Powell } 256f6148c53f93978af678cc0559a4417b608a33ae1Adam Powell 257f75eeb28def26798682748aa5dedabebac86bb6aAdam Powell public boolean hideOverflowMenu() { 2588515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell if (mPostedOpenRunnable != null) { 2598515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell removeCallbacks(mPostedOpenRunnable); 2608515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell return true; 2618515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 2628515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 2636c6f575423d6718c3ff322224c1520901ce881e1Adam Powell MenuPopupHelper popup = mOverflowPopup; 264f75eeb28def26798682748aa5dedabebac86bb6aAdam Powell if (popup != null) { 265f75eeb28def26798682748aa5dedabebac86bb6aAdam Powell popup.dismiss(); 2668028dd32a4a04154050220dd0693583d5b750330Adam Powell return true; 2678028dd32a4a04154050220dd0693583d5b750330Adam Powell } 2688028dd32a4a04154050220dd0693583d5b750330Adam Powell return false; 26996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 27096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 271be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private boolean addItemView(boolean needsDivider, ActionMenuItemView view) { 27296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell view.setItemInvoker(this); 273be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell boolean hasText = view.hasText(); 274be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 275be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell if (hasText && needsDivider) { 276be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell addView(makeDividerView(), makeDividerLayoutParams()); 277be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell } 27896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell addView(view); 279be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell return hasText; 280be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell } 281be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 282be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private ImageView makeDividerView() { 283be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell ImageView result = new ImageView(mContext); 284be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell result.setImageDrawable(mDivider); 285be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell result.setScaleType(ImageView.ScaleType.FIT_XY); 286be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell return result; 287be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell } 288be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 289be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell private LayoutParams makeDividerLayoutParams() { 290be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, 291be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell LayoutParams.MATCH_PARENT); 292be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell params.topMargin = (int) mDividerPadding; 293be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell params.bottomMargin = (int) mDividerPadding; 294be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell return params; 295be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell } 296be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 2973f476b34049d062942eafcf48396f593e00bd324Adam Powell private LayoutParams makeActionViewLayoutParams(View view) { 2983f476b34049d062942eafcf48396f593e00bd324Adam Powell LayoutParams params = generateLayoutParams(view.getLayoutParams()); 299be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell params.leftMargin = (int) mButtonPaddingLeft; 300be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell params.rightMargin = (int) mButtonPaddingRight; 301be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell return params; 30296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 3038028dd32a4a04154050220dd0693583d5b750330Adam Powell 3048028dd32a4a04154050220dd0693583d5b750330Adam Powell private class OverflowMenuButton extends ImageButton { 3058028dd32a4a04154050220dd0693583d5b750330Adam Powell public OverflowMenuButton(Context context) { 306079fd1c0a329b0fbd3761abe2e900a941131efedAdam Powell super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle); 3078028dd32a4a04154050220dd0693583d5b750330Adam Powell 3088028dd32a4a04154050220dd0693583d5b750330Adam Powell setClickable(true); 3098028dd32a4a04154050220dd0693583d5b750330Adam Powell setFocusable(true); 3108028dd32a4a04154050220dd0693583d5b750330Adam Powell setVisibility(VISIBLE); 3118028dd32a4a04154050220dd0693583d5b750330Adam Powell setEnabled(true); 3128028dd32a4a04154050220dd0693583d5b750330Adam Powell } 3138028dd32a4a04154050220dd0693583d5b750330Adam Powell 3148028dd32a4a04154050220dd0693583d5b750330Adam Powell @Override 3158028dd32a4a04154050220dd0693583d5b750330Adam Powell public boolean performClick() { 3168028dd32a4a04154050220dd0693583d5b750330Adam Powell if (super.performClick()) { 3178028dd32a4a04154050220dd0693583d5b750330Adam Powell return true; 3188028dd32a4a04154050220dd0693583d5b750330Adam Powell } 3198028dd32a4a04154050220dd0693583d5b750330Adam Powell 3208515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell showOverflowMenu(); 3218028dd32a4a04154050220dd0693583d5b750330Adam Powell return true; 3228028dd32a4a04154050220dd0693583d5b750330Adam Powell } 3238028dd32a4a04154050220dd0693583d5b750330Adam Powell } 3248515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 3258515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell private class OverflowPopup extends MenuPopupHelper { 3268515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell public OverflowPopup(Context context, MenuBuilder menu, View anchorView, 3278515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell boolean overflowOnly) { 3288515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell super(context, menu, anchorView, overflowOnly); 3298515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 3308515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 3318515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell @Override 3328515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell public void onDismiss() { 3338515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell super.onDismiss(); 3348515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mMenu.getCallback().onCloseMenu(mMenu, true); 3358515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell mOverflowPopup = null; 3368515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 3378515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 33896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell} 339