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; 2096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellimport android.util.AttributeSet; 216b336f835d637853800b94689375a03f337139a4Adam Powellimport android.view.Gravity; 22cf78b3e5101349fdddbde14b3a55140f9562ae66Adam Powellimport android.view.View; 23640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.view.ViewDebug; 247ade1be822ed05a143b059319dccd5e9f623b56dAdam Powellimport android.view.ViewGroup; 257bc3ca0dc52be52ecad1c0de8c62a6a4bf8141caAdam Powellimport android.view.accessibility.AccessibilityEvent; 2696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellimport android.widget.LinearLayout; 2796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 2896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell/** 2996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell * @hide 3096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell */ 3196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powellpublic class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvoker, MenuView { 3296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell private static final String TAG = "ActionMenuView"; 3396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 3435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell static final int MIN_CELL_SIZE = 56; // dips 35be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell static final int GENERATED_ITEM_PADDING = 4; // dips 3635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 3796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell private MenuBuilder mMenu; 387ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell 398028dd32a4a04154050220dd0693583d5b750330Adam Powell private boolean mReserveOverflow; 40696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private ActionMenuPresenter mPresenter; 41640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell private boolean mFormatItems; 4289b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell private int mFormatItemsWidth; 4335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell private int mMinCellSize; 44be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell private int mGeneratedItemPadding; 4535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell private int mMeasuredExtraWidth; 468515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell 4796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public ActionMenuView(Context context) { 4896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell this(context, null); 4996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 5096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 5196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public ActionMenuView(Context context, AttributeSet attrs) { 5296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell super(context, attrs); 53f16888f1e849b0bc0b9c17e5f833c4e2cd54c382Adam Powell setBaselineAligned(false); 54be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell final float density = context.getResources().getDisplayMetrics().density; 55be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell mMinCellSize = (int) (MIN_CELL_SIZE * density); 56be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density); 57773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell } 58773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell 59696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void setPresenter(ActionMenuPresenter presenter) { 60696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPresenter = presenter; 61696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 62696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 6335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell public boolean isExpandedFormat() { 6435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell return mFormatItems; 6535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 6635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 676c6f575423d6718c3ff322224c1520901ce881e1Adam Powell @Override 68773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell public void onConfigurationChanged(Configuration newConfig) { 698515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell super.onConfigurationChanged(newConfig); 70696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPresenter.updateMenuView(false); 716c6f575423d6718c3ff322224c1520901ce881e1Adam Powell 72696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mPresenter != null && mPresenter.isOverflowMenuShowing()) { 73696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPresenter.hideOverflowMenu(); 74696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPresenter.showOverflowMenu(); 756c6f575423d6718c3ff322224c1520901ce881e1Adam Powell } 76773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell } 77773b1b97fc0f01efc8cf1e17a1250a9b654b1b85Adam Powell 788515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell @Override 79640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 8035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // If we've been given an exact size to match, apply special formatting during layout. 8189b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell final boolean wasFormatted = mFormatItems; 8235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; 8389b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell 8489b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell if (wasFormatted != mFormatItems) { 8589b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell mFormatItemsWidth = 0; // Reset this when switching modes 8689b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell } 8789b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell 8889b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell // Special formatting can change whether items can fit as action buttons. 8989b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell // Kick the menu and update presenters when this changes. 9089b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell final int widthSize = MeasureSpec.getMode(widthMeasureSpec); 9189b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) { 9289b09da7b3b1e69264d9ec710c66eb2f891b313eAdam Powell mFormatItemsWidth = widthSize; 93640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mMenu.onItemsChanged(true); 94640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 9535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 9635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (mFormatItems) { 9735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec); 9835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } else { 9935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell super.onMeasure(widthMeasureSpec, heightMeasureSpec); 10035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 10135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 10235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 10335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) { 10435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // We already know the width mode is EXACTLY if we're here. 10535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 10635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int widthSize = MeasureSpec.getSize(widthMeasureSpec); 10735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int heightSize = MeasureSpec.getSize(heightMeasureSpec); 10835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 10935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int widthPadding = getPaddingLeft() + getPaddingRight(); 11035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int heightPadding = getPaddingTop() + getPaddingBottom(); 11135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 11235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell widthSize -= widthPadding; 11335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 11435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Divide the view into cells. 11535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int cellCount = widthSize / mMinCellSize; 11635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int cellSizeRemaining = widthSize % mMinCellSize; 1173bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell 1183bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell if (cellCount == 0) { 1193bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell // Give up, nothing fits. 1203bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell setMeasuredDimension(widthSize, 0); 1213bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell return; 1223bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell } 1233bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell 12435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int cellSize = mMinCellSize + cellSizeRemaining / cellCount; 12535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 12635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int cellsRemaining = cellCount; 12735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int maxChildHeight = 0; 12835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int maxCellsUsed = 0; 129160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell int expandableItemCount = 0; 13014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell int visibleItemCount = 0; 13114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell boolean hasOverflow = false; 13235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 13314b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64. 13414b7e2c1688914ba8b6854738981337d7c0653beAdam Powell long smallestItemsAt = 0; 13535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 13635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int childCount = getChildCount(); 13735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell for (int i = 0; i < childCount; i++) { 13835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final View child = getChildAt(i); 13914b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (child.getVisibility() == GONE) continue; 14014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell 141be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell final boolean isGeneratedItem = child instanceof ActionMenuItemView; 14214b7e2c1688914ba8b6854738981337d7c0653beAdam Powell visibleItemCount++; 14314b7e2c1688914ba8b6854738981337d7c0653beAdam Powell 144be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell if (isGeneratedItem) { 145be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell // Reset padding for generated menu item views; it may change below 146be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell // and views are recycled. 147be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0); 148be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell } 149be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell 15035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 15135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell lp.expanded = false; 15235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell lp.extraPixels = 0; 15335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell lp.cellsUsed = 0; 154160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell lp.expandable = false; 15514b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.leftMargin = 0; 15614b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.rightMargin = 0; 157be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText(); 15835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 15935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Overflow always gets 1 cell. No more, no less. 16035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining; 16135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 16235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable, 16335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell heightMeasureSpec, heightPadding); 16435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 16535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell maxCellsUsed = Math.max(maxCellsUsed, cellsUsed); 166160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell if (lp.expandable) expandableItemCount++; 16714b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (lp.isOverflowButton) hasOverflow = true; 16835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 16935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellsRemaining -= cellsUsed; 17035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight()); 17114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (cellsUsed == 1) smallestItemsAt |= (1 << i); 17235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 17335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 174be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell // When we have overflow and a single expanded (text) item, we want to try centering it 175be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell // visually in the available space even though overflow consumes some of it. 176be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2; 177be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell 17835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Divide space for remaining cells if we have items that can expand. 17935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Try distributing whole leftover cells to smaller items first. 18035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 18135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell boolean needsExpansion = false; 182160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell while (expandableItemCount > 0 && cellsRemaining > 0) { 18335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int minCells = Integer.MAX_VALUE; 18435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell long minCellsAt = 0; // Bit locations are indices of relevant child views 18535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int minCellsItemCount = 0; 18635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell for (int i = 0; i < childCount; i++) { 18735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final View child = getChildAt(i); 18835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 18935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 19035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Don't try to expand items that shouldn't. 191160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell if (!lp.expandable) continue; 19235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 19335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Mark indices of children that can receive an extra cell. 19435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (lp.cellsUsed < minCells) { 19535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell minCells = lp.cellsUsed; 19635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell minCellsAt = 1 << i; 19735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell minCellsItemCount = 1; 19835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } else if (lp.cellsUsed == minCells) { 19935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell minCellsAt |= 1 << i; 20035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell minCellsItemCount++; 20135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 20235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 20335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 20435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Items that get expanded will always be in the set of smallest items when we're done. 20514b7e2c1688914ba8b6854738981337d7c0653beAdam Powell smallestItemsAt |= minCellsAt; 20635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 207be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop. 20835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 209be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell // We have enough cells, all minimum size items will be incremented. 210be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell minCells++; 211be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell 212be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell for (int i = 0; i < childCount; i++) { 21335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final View child = getChildAt(i); 21435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 215be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell if ((minCellsAt & (1 << i)) == 0) { 216be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell // If this item is already at our small item count, mark it for later. 217be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i; 218be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell continue; 219be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell } 220be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell 221be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) { 222be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell // Add padding to this item such that it centers. 223be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0); 224be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell } 22535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell lp.cellsUsed++; 22635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell lp.expanded = true; 22735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellsRemaining--; 22835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 22935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 23035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell needsExpansion = true; 23135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 23235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 23335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Divide any space left that wouldn't divide along cell boundaries 23414b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // evenly among the smallest items 23514b7e2c1688914ba8b6854738981337d7c0653beAdam Powell 23614b7e2c1688914ba8b6854738981337d7c0653beAdam Powell final boolean singleItem = !hasOverflow && visibleItemCount == 1; 23714b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (cellsRemaining > 0 && smallestItemsAt != 0 && 238be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) { 23914b7e2c1688914ba8b6854738981337d7c0653beAdam Powell float expandCount = Long.bitCount(smallestItemsAt); 24014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell 24114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (!singleItem) { 24214b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // The items at the far edges may only expand by half in order to pin to either side. 24314b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if ((smallestItemsAt & 1) != 0) { 244be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams(); 245be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell if (!lp.preventEdgeOffset) expandCount -= 0.5f; 24614b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } 24714b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if ((smallestItemsAt & (1 << (childCount - 1))) != 0) { 248be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams()); 249be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell if (!lp.preventEdgeOffset) expandCount -= 0.5f; 25014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } 25114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } 25235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 2533bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell final int extraPixels = expandCount > 0 ? 2543bb421d5b85a8a99c408d16e4f80163a53bc0505Adam Powell (int) (cellsRemaining * cellSize / expandCount) : 0; 25535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 25635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell for (int i = 0; i < childCount; i++) { 25714b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if ((smallestItemsAt & (1 << i)) == 0) continue; 25835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 25935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final View child = getChildAt(i); 26035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 26114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (child instanceof ActionMenuItemView) { 26214b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // If this is one of our views, expand and measure at the larger size. 26314b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.extraPixels = extraPixels; 26414b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.expanded = true; 265be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell if (i == 0 && !lp.preventEdgeOffset) { 26614b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // First item gets part of its new padding pushed out of sight. 26714b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // The last item will get this implicitly from layout. 26814b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.leftMargin = -extraPixels / 2; 26914b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } 27014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell needsExpansion = true; 27114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } else if (lp.isOverflowButton) { 27214b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.extraPixels = extraPixels; 27314b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.expanded = true; 27414b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.rightMargin = -extraPixels / 2; 27514b7e2c1688914ba8b6854738981337d7c0653beAdam Powell needsExpansion = true; 27614b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } else { 27714b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // If we don't know what it is, give it some margins instead 27814b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // and let it center within its space. We still want to pin 27914b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // against the edges. 28014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (i != 0) { 28114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.leftMargin = extraPixels / 2; 28214b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } 28314b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (i != childCount - 1) { 28414b7e2c1688914ba8b6854738981337d7c0653beAdam Powell lp.rightMargin = extraPixels / 2; 28514b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } 28614b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } 28735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 28835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 28935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellsRemaining = 0; 29035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 29135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 29235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell // Remeasure any items that have had extra space allocated to them. 29335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (needsExpansion) { 29435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int heightSpec = MeasureSpec.makeMeasureSpec(heightSize - heightPadding, heightMode); 29535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell for (int i = 0; i < childCount; i++) { 29635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final View child = getChildAt(i); 29735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 29835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 29935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (!lp.expanded) continue; 30035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 30135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int width = lp.cellsUsed * cellSize + lp.extraPixels; 30235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec); 30335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 30435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 30535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 30635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (heightMode != MeasureSpec.EXACTLY) { 30735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell heightSize = maxChildHeight; 30835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 30935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 31035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell setMeasuredDimension(widthSize, heightSize); 31135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell mMeasuredExtraWidth = cellsRemaining * cellSize; 31235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 31335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 31435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell /** 31535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * Measure a child view to fit within cell-based formatting. The child's width 31635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * will be measured to a whole multiple of cellSize. 31735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * 318160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell * <p>Sets the expandable and cellsUsed fields of LayoutParams. 31935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * 32035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * @param child Child to measure 32135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * @param cellSize Size of one cell 32235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * @param cellsRemaining Number of cells remaining that this view can expand to fill 32335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * @param parentHeightMeasureSpec MeasureSpec used by the parent view 32435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * @param parentHeightPadding Padding present in the parent view 32535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell * @return Number of cells this child was measured to occupy 32635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell */ 32735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell static int measureChildForCells(View child, int cellSize, int cellsRemaining, 32835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int parentHeightMeasureSpec, int parentHeightPadding) { 32935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 33035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 33135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) - 33235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell parentHeightPadding; 33335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec); 33435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode); 33535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 336160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell int cellsUsed = 0; 337160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell if (cellsRemaining > 0) { 33835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int childWidthSpec = MeasureSpec.makeMeasureSpec( 33935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellSize * cellsRemaining, MeasureSpec.AT_MOST); 34035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell child.measure(childWidthSpec, childHeightSpec); 34135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 34235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int measuredWidth = child.getMeasuredWidth(); 34335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellsUsed = measuredWidth / cellSize; 34435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (measuredWidth % cellSize != 0) cellsUsed++; 34535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 346160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell 347160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell final ActionMenuItemView itemView = child instanceof ActionMenuItemView ? 348160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell (ActionMenuItemView) child : null; 349160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell final boolean expandable = !lp.isOverflowButton && itemView != null && itemView.hasText(); 350160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell lp.expandable = expandable; 351160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell 35235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell lp.cellsUsed = cellsUsed; 35335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int targetWidth = cellsUsed * cellSize; 35435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), 35535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell childHeightSpec); 35635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell return cellsUsed; 357640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 358640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 359640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell @Override 360640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 361640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (!mFormatItems) { 362640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell super.onLayout(changed, left, top, right, bottom); 363640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell return; 364640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 365640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 366640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell final int childCount = getChildCount(); 367640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell final int midVertical = (top + bottom) / 2; 368640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell final int dividerWidth = getDividerWidth(); 369640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int overflowWidth = 0; 370640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int nonOverflowWidth = 0; 371640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int nonOverflowCount = 0; 372640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int widthRemaining = right - left - getPaddingRight() - getPaddingLeft(); 37335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell boolean hasOverflow = false; 374640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell for (int i = 0; i < childCount; i++) { 375640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell final View v = getChildAt(i); 376640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (v.getVisibility() == GONE) { 377640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell continue; 378640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 379640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 380640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell LayoutParams p = (LayoutParams) v.getLayoutParams(); 381640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (p.isOverflowButton) { 382640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell overflowWidth = v.getMeasuredWidth(); 383640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (hasDividerBeforeChildAt(i)) { 384640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell overflowWidth += dividerWidth; 385640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 386640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 387640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int height = v.getMeasuredHeight(); 38814b7e2c1688914ba8b6854738981337d7c0653beAdam Powell int r = getWidth() - getPaddingRight() - p.rightMargin; 389640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int l = r - overflowWidth; 390640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int t = midVertical - (height / 2); 391640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int b = t + height; 392640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell v.layout(l, t, r, b); 393640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 394640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell widthRemaining -= overflowWidth; 39535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell hasOverflow = true; 396640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } else { 39735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin; 39835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell nonOverflowWidth += size; 39935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell widthRemaining -= size; 400640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (hasDividerBeforeChildAt(i)) { 401640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell nonOverflowWidth += dividerWidth; 402640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 403640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell nonOverflowCount++; 404640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 405640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 406640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 40714b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (childCount == 1 && !hasOverflow) { 40814b7e2c1688914ba8b6854738981337d7c0653beAdam Powell // Center a single child 40914b7e2c1688914ba8b6854738981337d7c0653beAdam Powell final View v = getChildAt(0); 41014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell final int width = v.getMeasuredWidth(); 41114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell final int height = v.getMeasuredHeight(); 41214b7e2c1688914ba8b6854738981337d7c0653beAdam Powell final int midHorizontal = (right - left) / 2; 41314b7e2c1688914ba8b6854738981337d7c0653beAdam Powell final int l = midHorizontal - width / 2; 41414b7e2c1688914ba8b6854738981337d7c0653beAdam Powell final int t = midVertical - height / 2; 41514b7e2c1688914ba8b6854738981337d7c0653beAdam Powell v.layout(l, t, l + width, t + height); 41614b7e2c1688914ba8b6854738981337d7c0653beAdam Powell return; 41714b7e2c1688914ba8b6854738981337d7c0653beAdam Powell } 41814b7e2c1688914ba8b6854738981337d7c0653beAdam Powell 41935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1); 42014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0); 421640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 422f4232e0097ffb672f5d1559b20c7230081efe34fAdam Powell int startLeft = getPaddingLeft(); 423640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell for (int i = 0; i < childCount; i++) { 424640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell final View v = getChildAt(i); 425640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell final LayoutParams lp = (LayoutParams) v.getLayoutParams(); 426640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (v.getVisibility() == GONE || lp.isOverflowButton) { 427640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell continue; 428640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 429640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 430640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell startLeft += lp.leftMargin; 431640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int width = v.getMeasuredWidth(); 432640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int height = v.getMeasuredHeight(); 43314b7e2c1688914ba8b6854738981337d7c0653beAdam Powell int t = midVertical - height / 2; 434640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell v.layout(startLeft, t, startLeft + width, t + height); 43535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell startLeft += width + lp.rightMargin + spacerSize; 436640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 437640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 438640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 439640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell @Override 4408515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell public void onDetachedFromWindow() { 4418515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell super.onDetachedFromWindow(); 442696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPresenter.dismissPopupMenus(); 4438028dd32a4a04154050220dd0693583d5b750330Adam Powell } 4448028dd32a4a04154050220dd0693583d5b750330Adam Powell 4458028dd32a4a04154050220dd0693583d5b750330Adam Powell public boolean isOverflowReserved() { 4468028dd32a4a04154050220dd0693583d5b750330Adam Powell return mReserveOverflow; 4477ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell } 4487ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell 449b366bbae2b5a3009893ef64246e3430cea4b7736Adam Powell public void setOverflowReserved(boolean reserveOverflow) { 450b366bbae2b5a3009893ef64246e3430cea4b7736Adam Powell mReserveOverflow = reserveOverflow; 451b366bbae2b5a3009893ef64246e3430cea4b7736Adam Powell } 452f0ad6e6eaf48ac8f4007232ad0a8511a7b5cfc0eAdam Powell 4537ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell @Override 4547ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell protected LayoutParams generateDefaultLayoutParams() { 4557ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, 4567ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell LayoutParams.WRAP_CONTENT); 4576b336f835d637853800b94689375a03f337139a4Adam Powell params.gravity = Gravity.CENTER_VERTICAL; 4587ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell return params; 4597ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell } 4607ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell 4617ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell @Override 46235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell public LayoutParams generateLayoutParams(AttributeSet attrs) { 46335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell return new LayoutParams(getContext(), attrs); 46435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 46535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 46635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell @Override 4677ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 4683f476b34049d062942eafcf48396f593e00bd324Adam Powell if (p instanceof LayoutParams) { 4693f476b34049d062942eafcf48396f593e00bd324Adam Powell LayoutParams result = new LayoutParams((LayoutParams) p); 4703f476b34049d062942eafcf48396f593e00bd324Adam Powell if (result.gravity <= Gravity.NO_GRAVITY) { 4713f476b34049d062942eafcf48396f593e00bd324Adam Powell result.gravity = Gravity.CENTER_VERTICAL; 4723f476b34049d062942eafcf48396f593e00bd324Adam Powell } 4733f476b34049d062942eafcf48396f593e00bd324Adam Powell return result; 4743f476b34049d062942eafcf48396f593e00bd324Adam Powell } 4757ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell return generateDefaultLayoutParams(); 4767ade1be822ed05a143b059319dccd5e9f623b56dAdam Powell } 47796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 478696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 479696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 48035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell return p != null && p instanceof LayoutParams; 481696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 482696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 483640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public LayoutParams generateOverflowButtonLayoutParams() { 484640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell LayoutParams result = generateDefaultLayoutParams(); 485640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell result.isOverflowButton = true; 486640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell return result; 487640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 488640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 48996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public boolean invokeItem(MenuItemImpl item) { 49096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell return mMenu.performItemAction(item, 0); 49196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 49296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 49396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell public int getWindowAnimations() { 49496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell return 0; 49596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell } 49696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell 497696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void initialize(MenuBuilder menu) { 49896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell mMenu = menu; 499f6148c53f93978af678cc0559a4417b608a33ae1Adam Powell } 500f6148c53f93978af678cc0559a4417b608a33ae1Adam Powell 501696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 502696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell protected boolean hasDividerBeforeChildAt(int childIndex) { 503696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final View childBefore = getChildAt(childIndex - 1); 504696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final View child = getChildAt(childIndex); 505696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell boolean result = false; 506696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (childIndex < getChildCount() && childBefore instanceof ActionMenuChildView) { 507696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell result |= ((ActionMenuChildView) childBefore).needsDividerAfter(); 5088028dd32a4a04154050220dd0693583d5b750330Adam Powell } 509696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (childIndex > 0 && child instanceof ActionMenuChildView) { 510696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell result |= ((ActionMenuChildView) child).needsDividerBefore(); 511be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell } 512be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell return result; 513be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell } 514be4d68e7b238b8ee879de0481e39c40d3f1683b6Adam Powell 5157bc3ca0dc52be52ecad1c0de8c62a6a4bf8141caAdam Powell public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 5167bc3ca0dc52be52ecad1c0de8c62a6a4bf8141caAdam Powell return false; 5177bc3ca0dc52be52ecad1c0de8c62a6a4bf8141caAdam Powell } 5187bc3ca0dc52be52ecad1c0de8c62a6a4bf8141caAdam Powell 519696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public interface ActionMenuChildView { 520696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean needsDividerBefore(); 521696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean needsDividerAfter(); 5228515ee846bd76aee86ec5ddfcc4dd1e626dd999cAdam Powell } 523640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 524640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public static class LayoutParams extends LinearLayout.LayoutParams { 525640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell @ViewDebug.ExportedProperty(category = "layout") 526640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public boolean isOverflowButton; 52735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell @ViewDebug.ExportedProperty(category = "layout") 52835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell public int cellsUsed; 52935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell @ViewDebug.ExportedProperty(category = "layout") 53035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell public int extraPixels; 531160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell @ViewDebug.ExportedProperty(category = "layout") 532160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell public boolean expandable; 533be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell @ViewDebug.ExportedProperty(category = "layout") 534be3c329ebec083e5ff933bab6b6c501519ad2bffAdam Powell public boolean preventEdgeOffset; 535160bb7fa60e8ece654e6ce999b6c16af50ee7357Adam Powell 53635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell public boolean expanded; 537640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 538640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public LayoutParams(Context c, AttributeSet attrs) { 539640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell super(c, attrs); 540640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 541640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 542640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public LayoutParams(LayoutParams other) { 543640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell super((LinearLayout.LayoutParams) other); 544640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell isOverflowButton = other.isOverflowButton; 545640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 546640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 547640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public LayoutParams(int width, int height) { 548640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell super(width, height); 549640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell isOverflowButton = false; 550640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 551640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 552640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public LayoutParams(int width, int height, boolean isOverflowButton) { 553640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell super(width, height); 554640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell this.isOverflowButton = isOverflowButton; 555640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 556640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 55796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell} 558