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