Home | History | Annotate | Download | only in menu
      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 
     51     public ActionMenuView(Context context) {
     52         this(context, null);
     53     }
     54 
     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 
     68     public void setPresenter(ActionMenuPresenter presenter) {
     69         mPresenter = presenter;
     70     }
     71 
     72     public boolean isExpandedFormat() {
     73         return mFormatItems;
     74     }
     75 
     76     public void setMaxItemHeight(int maxItemHeight) {
     77         mMaxItemHeight = maxItemHeight;
     78         requestLayout();
     79     }
     80 
     81     @Override
     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
     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 
    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      */
    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
    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
    495     public void onDetachedFromWindow() {
    496         super.onDetachedFromWindow();
    497         mPresenter.dismissPopupMenus();
    498     }
    499 
    500     public boolean isOverflowReserved() {
    501         return mReserveOverflow;
    502     }
    503 
    504     public void setOverflowReserved(boolean reserveOverflow) {
    505         mReserveOverflow = reserveOverflow;
    506     }
    507 
    508     @Override
    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
    517     public LayoutParams generateLayoutParams(AttributeSet attrs) {
    518         return new LayoutParams(getContext(), attrs);
    519     }
    520 
    521     @Override
    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
    536     protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
    537         return p != null && p instanceof LayoutParams;
    538     }
    539 
    540     public LayoutParams generateOverflowButtonLayoutParams() {
    541         LayoutParams result = generateDefaultLayoutParams();
    542         result.isOverflowButton = true;
    543         return result;
    544     }
    545 
    546     public boolean invokeItem(MenuItemImpl item) {
    547         return mMenu.performItemAction(item, 0);
    548     }
    549 
    550     public int getWindowAnimations() {
    551         return 0;
    552     }
    553 
    554     public void initialize(MenuBuilder menu) {
    555         mMenu = menu;
    556     }
    557 
    558     @Override
    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 
    575     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
    576         return false;
    577     }
    578 
    579     public interface ActionMenuChildView {
    580         public boolean needsDividerBefore();
    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 
    598         public LayoutParams(Context c, AttributeSet attrs) {
    599             super(c, attrs);
    600         }
    601 
    602         public LayoutParams(ViewGroup.LayoutParams other) {
    603             super(other);
    604         }
    605 
    606         public LayoutParams(LayoutParams other) {
    607             super((LinearLayout.LayoutParams) other);
    608             isOverflowButton = other.isOverflowButton;
    609         }
    610 
    611         public LayoutParams(int width, int height) {
    612             super(width, height);
    613             isOverflowButton = false;
    614         }
    615 
    616         public LayoutParams(int width, int height, boolean isOverflowButton) {
    617             super(width, height);
    618             this.isOverflowButton = isOverflowButton;
    619         }
    620     }
    621 }
    622