ActionMenuView.java revision bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17f
1bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/*
2bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Copyright (C) 2010 The Android Open Source Project
3bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
4bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * you may not use this file except in compliance with the License.
6bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * You may obtain a copy of the License at
7bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
8bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
10bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Unless required by applicable law or agreed to in writing, software
11bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * See the License for the specific language governing permissions and
14bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * limitations under the License.
15bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */
16bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellpackage android.support.appcompat.view.menu;
17bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
18bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context;
19bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.Configuration;
20bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.TypedArray;
21bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.support.appcompat.R;
22bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.AttributeSet;
23bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.Gravity;
24bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View;
25bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.ViewDebug;
26bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.ViewGroup;
27bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.accessibility.AccessibilityEvent;
28bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.widget.LinearLayout;
29bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
30bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/**
31bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * @hide
32bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */
33bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellpublic class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvoker, MenuView {
34bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private static final String TAG = "ActionMenuView";
35bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
36bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  static final int MIN_CELL_SIZE = 56; // dips
37bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  static final int GENERATED_ITEM_PADDING = 4; // dips
38bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
39bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private MenuBuilder mMenu;
40bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
41bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private boolean mReserveOverflow;
42bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private ActionMenuPresenter mPresenter;
43bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private boolean mFormatItems;
44bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private int mFormatItemsWidth;
45bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private int mMinCellSize;
46bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private int mGeneratedItemPadding;
47bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private int mMeasuredExtraWidth;
48bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private int mMaxItemHeight;
49bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
50bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public ActionMenuView(Context context) {
51bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    this(context, null);
52bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
53bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
54bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public ActionMenuView(Context context, AttributeSet attrs) {
55bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    super(context, attrs);
56bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    setBaselineAligned(false);
57bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final float density = context.getResources().getDisplayMetrics().density;
58bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mMinCellSize = (int) (MIN_CELL_SIZE * density);
59bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density);
60bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
61bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar,
62bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        R.attr.actionBarStyle, 0);
63bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mMaxItemHeight = a.getDimensionPixelSize(R.styleable.ActionBar_height, 0);
64bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    a.recycle();
65bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
66bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
67bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void setPresenter(ActionMenuPresenter presenter) {
68bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mPresenter = presenter;
69bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
70bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
71bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public boolean isExpandedFormat() {
72bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return mFormatItems;
73bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
74bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
75bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
76bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void onConfigurationChanged(Configuration newConfig) {
77bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    super.onConfigurationChanged(newConfig);
78bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mPresenter.updateMenuView(false);
79bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
80bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mPresenter != null && mPresenter.isOverflowMenuShowing()) {
81bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      mPresenter.hideOverflowMenu();
82bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      mPresenter.showOverflowMenu();
83bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
84bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
85bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
86bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
87bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
88bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // If we've been given an exact size to match, apply special formatting during layout.
89bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final boolean wasFormatted = mFormatItems;
90bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
91bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
92bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (wasFormatted != mFormatItems) {
93bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      mFormatItemsWidth = 0; // Reset this when switching modes
94bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
95bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
96bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Special formatting can change whether items can fit as action buttons.
97bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Kick the menu and update presenters when this changes.
98bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int widthSize = MeasureSpec.getMode(widthMeasureSpec);
99bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) {
100bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      mFormatItemsWidth = widthSize;
101bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      mMenu.onItemsChanged(true);
102bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
103bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
104bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mFormatItems) {
105bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec);
106bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    } else {
107bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      // Previous measurement at exact format may have set margins - reset them.
108bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int childCount = getChildCount();
109bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      for (int i = 0; i < childCount; i++) {
110bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final View child = getChildAt(i);
111bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
112bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        lp.leftMargin = lp.rightMargin = 0;
113bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
114bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
115bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
116bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
117bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
118bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) {
119bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // We already know the width mode is EXACTLY if we're here.
120bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
121bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
122bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
123bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
124bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int widthPadding = getPaddingLeft() + getPaddingRight();
125bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int heightPadding = getPaddingTop() + getPaddingBottom();
126bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
127bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int itemHeightSpec = heightMode == MeasureSpec.EXACTLY
128bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        ? MeasureSpec.makeMeasureSpec(heightSize - heightPadding, MeasureSpec.EXACTLY)
129bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        : MeasureSpec.makeMeasureSpec(
130bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell            Math.min(mMaxItemHeight, heightSize - heightPadding), MeasureSpec.AT_MOST);
131bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
132bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    widthSize -= widthPadding;
133bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
134bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Divide the view into cells.
135bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int cellCount = widthSize / mMinCellSize;
136bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int cellSizeRemaining = widthSize % mMinCellSize;
137bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
138bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (cellCount == 0) {
139bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      // Give up, nothing fits.
140bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      setMeasuredDimension(widthSize, 0);
141bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      return;
142bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
143bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
144bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int cellSize = mMinCellSize + cellSizeRemaining / cellCount;
145bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
146bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int cellsRemaining = cellCount;
147bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int maxChildHeight = 0;
148bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int maxCellsUsed = 0;
149bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int expandableItemCount = 0;
150bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int visibleItemCount = 0;
151bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    boolean hasOverflow = false;
152bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
153bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64.
154bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    long smallestItemsAt = 0;
155bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
156bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int childCount = getChildCount();
157bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    for (int i = 0; i < childCount; i++) {
158bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final View child = getChildAt(i);
159bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (child.getVisibility() == GONE) continue;
160bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
161bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final boolean isGeneratedItem = child instanceof ActionMenuItemView;
162bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      visibleItemCount++;
163bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
164bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (isGeneratedItem) {
165bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        // Reset padding for generated menu item views; it may change below
166bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        // and views are recycled.
167bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0);
168bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
169bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
170bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final LayoutParams lp = (LayoutParams) child.getLayoutParams();
171bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      lp.expanded = false;
172bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      lp.extraPixels = 0;
173bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      lp.cellsUsed = 0;
174bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      lp.expandable = false;
175bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      lp.leftMargin = 0;
176bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      lp.rightMargin = 0;
177bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText();
178bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
179bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      // Overflow always gets 1 cell. No more, no less.
180bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining;
181bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
182bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable,
183bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          itemHeightSpec, heightPadding);
184bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
185bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      maxCellsUsed = Math.max(maxCellsUsed, cellsUsed);
186bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (lp.expandable) expandableItemCount++;
187bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (lp.isOverflowButton) hasOverflow = true;
188bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
189bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      cellsRemaining -= cellsUsed;
190bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
191bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (cellsUsed == 1) smallestItemsAt |= (1 << i);
192bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
193bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
194bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // When we have overflow and a single expanded (text) item, we want to try centering it
195bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // visually in the available space even though overflow consumes some of it.
196bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2;
197bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
198bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Divide space for remaining cells if we have items that can expand.
199bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Try distributing whole leftover cells to smaller items first.
200bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
201bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    boolean needsExpansion = false;
202bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    while (expandableItemCount > 0 && cellsRemaining > 0) {
203bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      int minCells = Integer.MAX_VALUE;
204bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      long minCellsAt = 0; // Bit locations are indices of relevant child views
205bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      int minCellsItemCount = 0;
206bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      for (int i = 0; i < childCount; i++) {
207bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final View child = getChildAt(i);
208bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
209bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
210bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        // Don't try to expand items that shouldn't.
211bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if (!lp.expandable) continue;
212bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
213bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        // Mark indices of children that can receive an extra cell.
214bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if (lp.cellsUsed < minCells) {
215bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          minCells = lp.cellsUsed;
216bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          minCellsAt = 1 << i;
217bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          minCellsItemCount = 1;
218bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        } else if (lp.cellsUsed == minCells) {
219bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          minCellsAt |= 1 << i;
220bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          minCellsItemCount++;
221bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
222bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
223bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
224bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      // Items that get expanded will always be in the set of smallest items when we're done.
225bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      smallestItemsAt |= minCellsAt;
226bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
227bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
228bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
229bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      // We have enough cells, all minimum size items will be incremented.
230bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      minCells++;
231bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
232bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      for (int i = 0; i < childCount; i++) {
233bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final View child = getChildAt(i);
234bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
235bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if ((minCellsAt & (1 << i)) == 0) {
236bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          // If this item is already at our small item count, mark it for later.
237bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i;
238bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          continue;
239bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
240bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
241bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) {
242bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          // Add padding to this item such that it centers.
243bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0);
244bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
245bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        lp.cellsUsed++;
246bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        lp.expanded = true;
247bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        cellsRemaining--;
248bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
249bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
250bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      needsExpansion = true;
251bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
252bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
253bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Divide any space left that wouldn't divide along cell boundaries
254bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // evenly among the smallest items
255bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
256bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final boolean singleItem = !hasOverflow && visibleItemCount == 1;
257bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (cellsRemaining > 0 && smallestItemsAt != 0 &&
258bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) {
259bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      float expandCount = Long.bitCount(smallestItemsAt);
260bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
261bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (!singleItem) {
262bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        // The items at the far edges may only expand by half in order to pin to either side.
263bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if ((smallestItemsAt & 1) != 0) {
264bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams();
265bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          if (!lp.preventEdgeOffset) expandCount -= 0.5f;
266bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
267bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if ((smallestItemsAt & (1 << (childCount - 1))) != 0) {
268bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams());
269bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          if (!lp.preventEdgeOffset) expandCount -= 0.5f;
270bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
271bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
272bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
273bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int extraPixels = expandCount > 0 ?
274bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          (int) (cellsRemaining * cellSize / expandCount) : 0;
275bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
276bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      for (int i = 0; i < childCount; i++) {
277bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if ((smallestItemsAt & (1 << i)) == 0) continue;
278bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
279bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final View child = getChildAt(i);
280bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
281bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if (child instanceof ActionMenuItemView) {
282bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          // If this is one of our views, expand and measure at the larger size.
283bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          lp.extraPixels = extraPixels;
284bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          lp.expanded = true;
285bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          if (i == 0 && !lp.preventEdgeOffset) {
286bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell            // First item gets part of its new padding pushed out of sight.
287bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell            // The last item will get this implicitly from layout.
288bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell            lp.leftMargin = -extraPixels / 2;
289bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          }
290bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          needsExpansion = true;
291bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        } else if (lp.isOverflowButton) {
292bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          lp.extraPixels = extraPixels;
293bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          lp.expanded = true;
294bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          lp.rightMargin = -extraPixels / 2;
295bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          needsExpansion = true;
296bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        } else {
297bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          // If we don't know what it is, give it some margins instead
298bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          // and let it center within its space. We still want to pin
299bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          // against the edges.
300bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          if (i != 0) {
301bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell            lp.leftMargin = extraPixels / 2;
302bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          }
303bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          if (i != childCount - 1) {
304bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell            lp.rightMargin = extraPixels / 2;
305bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          }
306bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
307bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
308bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
309bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      cellsRemaining = 0;
310bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
311bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
312bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Remeasure any items that have had extra space allocated to them.
313bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (needsExpansion) {
314bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      for (int i = 0; i < childCount; i++) {
315bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final View child = getChildAt(i);
316bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
317bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
318bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        if (!lp.expanded) continue;
319bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
320bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final int width = lp.cellsUsed * cellSize + lp.extraPixels;
321bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
322bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell            itemHeightSpec);
323bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
324bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
325bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
326bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (heightMode != MeasureSpec.EXACTLY) {
327bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      heightSize = maxChildHeight;
328bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
329bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
330bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    setMeasuredDimension(widthSize, heightSize);
331bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mMeasuredExtraWidth = cellsRemaining * cellSize;
332bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
333bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
334bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  /**
335bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * Measure a child view to fit within cell-based formatting. The child's width
336bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * will be measured to a whole multiple of cellSize.
337bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   *
338bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * <p>Sets the expandable and cellsUsed fields of LayoutParams.
339bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   *
340bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @param child Child to measure
341bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @param cellSize Size of one cell
342bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @param cellsRemaining Number of cells remaining that this view can expand to fill
343bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @param parentHeightMeasureSpec MeasureSpec used by the parent view
344bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @param parentHeightPadding Padding present in the parent view
345bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @return Number of cells this child was measured to occupy
346bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   */
347bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  static int measureChildForCells(View child, int cellSize, int cellsRemaining,
348bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      int parentHeightMeasureSpec, int parentHeightPadding) {
349bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final LayoutParams lp = (LayoutParams) child.getLayoutParams();
350bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
351bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) -
352bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        parentHeightPadding;
353bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec);
354bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode);
355bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
356bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final ActionMenuItemView itemView = child instanceof ActionMenuItemView ?
357bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        (ActionMenuItemView) child : null;
358bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final boolean hasText = itemView != null && itemView.hasText();
359bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
360bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int cellsUsed = 0;
361bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (cellsRemaining > 0 && (!hasText || cellsRemaining >= 2)) {
362bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int childWidthSpec = MeasureSpec.makeMeasureSpec(
363bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          cellSize * cellsRemaining, MeasureSpec.AT_MOST);
364bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      child.measure(childWidthSpec, childHeightSpec);
365bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
366bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int measuredWidth = child.getMeasuredWidth();
367bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      cellsUsed = measuredWidth / cellSize;
368bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (measuredWidth % cellSize != 0) cellsUsed++;
369bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (hasText && cellsUsed < 2) cellsUsed = 2;
370bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
371bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
372bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final boolean expandable = !lp.isOverflowButton && hasText;
373bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    lp.expandable = expandable;
374bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
375bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    lp.cellsUsed = cellsUsed;
376bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int targetWidth = cellsUsed * cellSize;
377bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY),
378bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        childHeightSpec);
379bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return cellsUsed;
380bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
381bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
382bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
383bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
384bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (!mFormatItems) {
385bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      super.onLayout(changed, left, top, right, bottom);
386bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      return;
387bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
388bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
389bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int childCount = getChildCount();
390bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int midVertical = (top + bottom) / 2;
391bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    //final int dividerWidth = getDividerWidth();  No access outside framework
392bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int overflowWidth = 0;
393bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int nonOverflowWidth = 0;
394bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int nonOverflowCount = 0;
395bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int widthRemaining = right - left - getPaddingRight() - getPaddingLeft();
396bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    boolean hasOverflow = false;
397bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    for (int i = 0; i < childCount; i++) {
398bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final View v = getChildAt(i);
399bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (v.getVisibility() == GONE) {
400bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        continue;
401bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
402bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
403bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      LayoutParams p = (LayoutParams) v.getLayoutParams();
404bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (p.isOverflowButton) {
405bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        overflowWidth = v.getMeasuredWidth();
406bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell// No access to dividerWidth
407bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell//        if (hasDividerBeforeChildAt(i)) {
408bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell//          overflowWidth += dividerWidth;
409bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell//        }
410bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
411bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        int height = v.getMeasuredHeight();
412bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        int r = getWidth() - getPaddingRight() - p.rightMargin;
413bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        int l = r - overflowWidth;
414bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        int t = midVertical - (height / 2);
415bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        int b = t + height;
416bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        v.layout(l, t, r, b);
417bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
418bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        widthRemaining -= overflowWidth;
419bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        hasOverflow = true;
420bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      } else {
421bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin;
422bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        nonOverflowWidth += size;
423bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        widthRemaining -= size;
424bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell// No access to dividerWidth
425bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell//        if (hasDividerBeforeChildAt(i)) {
426bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell//          nonOverflowWidth += dividerWidth;
427bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell//        }
428bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        nonOverflowCount++;
429bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
430bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
431bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
432bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (childCount == 1 && !hasOverflow) {
433bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      // Center a single child
434bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final View v = getChildAt(0);
435bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int width = v.getMeasuredWidth();
436bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int height = v.getMeasuredHeight();
437bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int midHorizontal = (right - left) / 2;
438bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int l = midHorizontal - width / 2;
439bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final int t = midVertical - height / 2;
440bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      v.layout(l, t, l + width, t + height);
441bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      return;
442bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
443bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
444bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1);
445bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0);
446bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
447bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int startLeft = getPaddingLeft();
448bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    for (int i = 0; i < childCount; i++) {
449bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final View v = getChildAt(i);
450bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      final LayoutParams lp = (LayoutParams) v.getLayoutParams();
451bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (v.getVisibility() == GONE || lp.isOverflowButton) {
452bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        continue;
453bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
454bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
455bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      startLeft += lp.leftMargin;
456bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      int width = v.getMeasuredWidth();
457bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      int height = v.getMeasuredHeight();
458bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      int t = midVertical - height / 2;
459bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      v.layout(startLeft, t, startLeft + width, t + height);
460bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      startLeft += width + lp.rightMargin + spacerSize;
461bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
462bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
463bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
464bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
465bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void onDetachedFromWindow() {
466bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    super.onDetachedFromWindow();
467bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mPresenter.dismissPopupMenus();
468bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
469bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
470bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public boolean isOverflowReserved() {
471bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return mReserveOverflow;
472bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
473bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
474bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void setOverflowReserved(boolean reserveOverflow) {
475bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mReserveOverflow = reserveOverflow;
476bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
477bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
478bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
479bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected LayoutParams generateDefaultLayoutParams() {
480bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
481bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        LayoutParams.WRAP_CONTENT);
482bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    params.gravity = Gravity.CENTER_VERTICAL;
483bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return params;
484bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
485bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
486bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
487bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public LayoutParams generateLayoutParams(AttributeSet attrs) {
488bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return new LayoutParams(getContext(), attrs);
489bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
490bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
491bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
492bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
493bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (p instanceof LayoutParams) {
494bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      LayoutParams result = new LayoutParams((LayoutParams) p);
495bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      if (result.gravity <= Gravity.NO_GRAVITY) {
496bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        result.gravity = Gravity.CENTER_VERTICAL;
497bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
498bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      return result;
499bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
500bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return generateDefaultLayoutParams();
501bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
502bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
503bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
504bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
505bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return p != null && p instanceof LayoutParams;
506bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
507bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
508bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public LayoutParams generateOverflowButtonLayoutParams() {
509bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    LayoutParams result = generateDefaultLayoutParams();
510bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    result.isOverflowButton = true;
511bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return result;
512bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
513bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
514bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public boolean invokeItem(MenuItemImpl item) {
515bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return mMenu.performItemAction(item, 0);
516bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
517bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
518bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public int getWindowAnimations() {
519bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return 0;
520bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
521bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
522bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void initialize(MenuBuilder menu) {
523bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mMenu = menu;
524bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
525bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
526bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected boolean hasDividerBeforeChildAt(int childIndex) {
527bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final View childBefore = getChildAt(childIndex - 1);
528bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    final View child = getChildAt(childIndex);
529bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    boolean result = false;
530bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (childIndex < getChildCount() && childBefore instanceof ActionMenuChildView) {
531bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      result |= ((ActionMenuChildView) childBefore).needsDividerAfter();
532bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
533bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (childIndex > 0 && child instanceof ActionMenuChildView) {
534bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      result |= ((ActionMenuChildView) child).needsDividerBefore();
535bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
536bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return result;
537bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
538bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
539bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
540bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return false;
541bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
542bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
543bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public interface ActionMenuChildView {
544bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public boolean needsDividerBefore();
545bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public boolean needsDividerAfter();
546bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
547bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
548bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public static class LayoutParams extends LinearLayout.LayoutParams {
549bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @ViewDebug.ExportedProperty(category = "layout")
550bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public boolean isOverflowButton;
551bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @ViewDebug.ExportedProperty(category = "layout")
552bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public int cellsUsed;
553bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @ViewDebug.ExportedProperty(category = "layout")
554bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public int extraPixels;
555bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @ViewDebug.ExportedProperty(category = "layout")
556bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public boolean expandable;
557bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @ViewDebug.ExportedProperty(category = "layout")
558bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public boolean preventEdgeOffset;
559bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
560bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public boolean expanded;
561bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
562bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public LayoutParams(Context c, AttributeSet attrs) {
563bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      super(c, attrs);
564bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
565bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
566bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public LayoutParams(LayoutParams other) {
567bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      super((LinearLayout.LayoutParams) other);
568bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      isOverflowButton = other.isOverflowButton;
569bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
570bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
571bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public LayoutParams(int width, int height) {
572bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      super(width, height);
573bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      isOverflowButton = false;
574bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
575bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
576bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    public LayoutParams(int width, int height, boolean isOverflowButton) {
577bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      super(width, height);
578bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      this.isOverflowButton = isOverflowButton;
579bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
580bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
581bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell}
582