Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2006 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 
     17 package android.widget;
     18 
     19 import java.util.ArrayList;
     20 
     21 import android.content.Context;
     22 import android.content.res.TypedArray;
     23 import android.graphics.Canvas;
     24 import android.graphics.Rect;
     25 import android.graphics.Region;
     26 import android.graphics.drawable.Drawable;
     27 import android.util.AttributeSet;
     28 import android.view.Gravity;
     29 import android.view.View;
     30 import android.view.ViewDebug;
     31 import android.view.ViewGroup;
     32 import android.view.accessibility.AccessibilityEvent;
     33 import android.view.accessibility.AccessibilityNodeInfo;
     34 import android.widget.RemoteViews.RemoteView;
     35 
     36 
     37 /**
     38  * FrameLayout is designed to block out an area on the screen to display
     39  * a single item. Generally, FrameLayout should be used to hold a single child view, because it can
     40  * be difficult to organize child views in a way that's scalable to different screen sizes without
     41  * the children overlapping each other. You can, however, add multiple children to a FrameLayout
     42  * and control their position within the FrameLayout by assigning gravity to each child, using the
     43  * <a href="FrameLayout.LayoutParams.html#attr_android:layout_gravity">{@code
     44  * android:layout_gravity}</a> attribute.
     45  * <p>Child views are drawn in a stack, with the most recently added child on top.
     46  * The size of the FrameLayout is the size of its largest child (plus padding), visible
     47  * or not (if the FrameLayout's parent permits). Views that are {@link android.view.View#GONE} are
     48  * used for sizing
     49  * only if {@link #setMeasureAllChildren(boolean) setConsiderGoneChildrenWhenMeasuring()}
     50  * is set to true.
     51  *
     52  * @attr ref android.R.styleable#FrameLayout_foreground
     53  * @attr ref android.R.styleable#FrameLayout_foregroundGravity
     54  * @attr ref android.R.styleable#FrameLayout_measureAllChildren
     55  */
     56 @RemoteView
     57 public class FrameLayout extends ViewGroup {
     58     private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.START;
     59 
     60     @ViewDebug.ExportedProperty(category = "measurement")
     61     boolean mMeasureAllChildren = false;
     62 
     63     @ViewDebug.ExportedProperty(category = "drawing")
     64     private Drawable mForeground;
     65 
     66     @ViewDebug.ExportedProperty(category = "padding")
     67     private int mForegroundPaddingLeft = 0;
     68 
     69     @ViewDebug.ExportedProperty(category = "padding")
     70     private int mForegroundPaddingTop = 0;
     71 
     72     @ViewDebug.ExportedProperty(category = "padding")
     73     private int mForegroundPaddingRight = 0;
     74 
     75     @ViewDebug.ExportedProperty(category = "padding")
     76     private int mForegroundPaddingBottom = 0;
     77 
     78     private final Rect mSelfBounds = new Rect();
     79     private final Rect mOverlayBounds = new Rect();
     80 
     81     @ViewDebug.ExportedProperty(category = "drawing")
     82     private int mForegroundGravity = Gravity.FILL;
     83 
     84     /** {@hide} */
     85     @ViewDebug.ExportedProperty(category = "drawing")
     86     protected boolean mForegroundInPadding = true;
     87 
     88     boolean mForegroundBoundsChanged = false;
     89 
     90     private final ArrayList<View> mMatchParentChildren = new ArrayList<View>(1);
     91 
     92     public FrameLayout(Context context) {
     93         super(context);
     94     }
     95 
     96     public FrameLayout(Context context, AttributeSet attrs) {
     97         this(context, attrs, 0);
     98     }
     99 
    100     public FrameLayout(Context context, AttributeSet attrs, int defStyle) {
    101         super(context, attrs, defStyle);
    102 
    103         TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.FrameLayout,
    104                     defStyle, 0);
    105 
    106         mForegroundGravity = a.getInt(
    107                 com.android.internal.R.styleable.FrameLayout_foregroundGravity, mForegroundGravity);
    108 
    109         final Drawable d = a.getDrawable(com.android.internal.R.styleable.FrameLayout_foreground);
    110         if (d != null) {
    111             setForeground(d);
    112         }
    113 
    114         if (a.getBoolean(com.android.internal.R.styleable.FrameLayout_measureAllChildren, false)) {
    115             setMeasureAllChildren(true);
    116         }
    117 
    118         mForegroundInPadding = a.getBoolean(
    119                 com.android.internal.R.styleable.FrameLayout_foregroundInsidePadding, true);
    120 
    121         a.recycle();
    122     }
    123 
    124     /**
    125      * Describes how the foreground is positioned.
    126      *
    127      * @return foreground gravity.
    128      *
    129      * @see #setForegroundGravity(int)
    130      *
    131      * @attr ref android.R.styleable#FrameLayout_foregroundGravity
    132      */
    133     public int getForegroundGravity() {
    134         return mForegroundGravity;
    135     }
    136 
    137     /**
    138      * Describes how the foreground is positioned. Defaults to START and TOP.
    139      *
    140      * @param foregroundGravity See {@link android.view.Gravity}
    141      *
    142      * @see #getForegroundGravity()
    143      *
    144      * @attr ref android.R.styleable#FrameLayout_foregroundGravity
    145      */
    146     @android.view.RemotableViewMethod
    147     public void setForegroundGravity(int foregroundGravity) {
    148         if (mForegroundGravity != foregroundGravity) {
    149             if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
    150                 foregroundGravity |= Gravity.START;
    151             }
    152 
    153             if ((foregroundGravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
    154                 foregroundGravity |= Gravity.TOP;
    155             }
    156 
    157             mForegroundGravity = foregroundGravity;
    158 
    159 
    160             if (mForegroundGravity == Gravity.FILL && mForeground != null) {
    161                 Rect padding = new Rect();
    162                 if (mForeground.getPadding(padding)) {
    163                     mForegroundPaddingLeft = padding.left;
    164                     mForegroundPaddingTop = padding.top;
    165                     mForegroundPaddingRight = padding.right;
    166                     mForegroundPaddingBottom = padding.bottom;
    167                 }
    168             } else {
    169                 mForegroundPaddingLeft = 0;
    170                 mForegroundPaddingTop = 0;
    171                 mForegroundPaddingRight = 0;
    172                 mForegroundPaddingBottom = 0;
    173             }
    174 
    175             requestLayout();
    176         }
    177     }
    178 
    179     /**
    180      * {@inheritDoc}
    181      */
    182     @Override
    183     protected boolean verifyDrawable(Drawable who) {
    184         return super.verifyDrawable(who) || (who == mForeground);
    185     }
    186 
    187     @Override
    188     public void jumpDrawablesToCurrentState() {
    189         super.jumpDrawablesToCurrentState();
    190         if (mForeground != null) mForeground.jumpToCurrentState();
    191     }
    192 
    193     /**
    194      * {@inheritDoc}
    195      */
    196     @Override
    197     protected void drawableStateChanged() {
    198         super.drawableStateChanged();
    199         if (mForeground != null && mForeground.isStateful()) {
    200             mForeground.setState(getDrawableState());
    201         }
    202     }
    203 
    204     /**
    205      * Returns a set of layout parameters with a width of
    206      * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT},
    207      * and a height of {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}.
    208      */
    209     @Override
    210     protected LayoutParams generateDefaultLayoutParams() {
    211         return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    212     }
    213 
    214     /**
    215      * Supply a Drawable that is to be rendered on top of all of the child
    216      * views in the frame layout.  Any padding in the Drawable will be taken
    217      * into account by ensuring that the children are inset to be placed
    218      * inside of the padding area.
    219      *
    220      * @param drawable The Drawable to be drawn on top of the children.
    221      *
    222      * @attr ref android.R.styleable#FrameLayout_foreground
    223      */
    224     public void setForeground(Drawable drawable) {
    225         if (mForeground != drawable) {
    226             if (mForeground != null) {
    227                 mForeground.setCallback(null);
    228                 unscheduleDrawable(mForeground);
    229             }
    230 
    231             mForeground = drawable;
    232             mForegroundPaddingLeft = 0;
    233             mForegroundPaddingTop = 0;
    234             mForegroundPaddingRight = 0;
    235             mForegroundPaddingBottom = 0;
    236 
    237             if (drawable != null) {
    238                 setWillNotDraw(false);
    239                 drawable.setCallback(this);
    240                 if (drawable.isStateful()) {
    241                     drawable.setState(getDrawableState());
    242                 }
    243                 if (mForegroundGravity == Gravity.FILL) {
    244                     Rect padding = new Rect();
    245                     if (drawable.getPadding(padding)) {
    246                         mForegroundPaddingLeft = padding.left;
    247                         mForegroundPaddingTop = padding.top;
    248                         mForegroundPaddingRight = padding.right;
    249                         mForegroundPaddingBottom = padding.bottom;
    250                     }
    251                 }
    252             }  else {
    253                 setWillNotDraw(true);
    254             }
    255             requestLayout();
    256             invalidate();
    257         }
    258     }
    259 
    260     /**
    261      * Returns the drawable used as the foreground of this FrameLayout. The
    262      * foreground drawable, if non-null, is always drawn on top of the children.
    263      *
    264      * @return A Drawable or null if no foreground was set.
    265      */
    266     public Drawable getForeground() {
    267         return mForeground;
    268     }
    269 
    270     int getPaddingLeftWithForeground() {
    271         return mForegroundInPadding ? Math.max(mPaddingLeft, mForegroundPaddingLeft) :
    272             mPaddingLeft + mForegroundPaddingLeft;
    273     }
    274 
    275     int getPaddingRightWithForeground() {
    276         return mForegroundInPadding ? Math.max(mPaddingRight, mForegroundPaddingRight) :
    277             mPaddingRight + mForegroundPaddingRight;
    278     }
    279 
    280     private int getPaddingTopWithForeground() {
    281         return mForegroundInPadding ? Math.max(mPaddingTop, mForegroundPaddingTop) :
    282             mPaddingTop + mForegroundPaddingTop;
    283     }
    284 
    285     private int getPaddingBottomWithForeground() {
    286         return mForegroundInPadding ? Math.max(mPaddingBottom, mForegroundPaddingBottom) :
    287             mPaddingBottom + mForegroundPaddingBottom;
    288     }
    289 
    290 
    291     /**
    292      * {@inheritDoc}
    293      */
    294     @Override
    295     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    296         int count = getChildCount();
    297 
    298         final boolean measureMatchParentChildren =
    299                 MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
    300                 MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
    301         mMatchParentChildren.clear();
    302 
    303         int maxHeight = 0;
    304         int maxWidth = 0;
    305         int childState = 0;
    306 
    307         for (int i = 0; i < count; i++) {
    308             final View child = getChildAt(i);
    309             if (mMeasureAllChildren || child.getVisibility() != GONE) {
    310                 measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
    311                 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
    312                 maxWidth = Math.max(maxWidth,
    313                         child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
    314                 maxHeight = Math.max(maxHeight,
    315                         child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
    316                 childState = combineMeasuredStates(childState, child.getMeasuredState());
    317                 if (measureMatchParentChildren) {
    318                     if (lp.width == LayoutParams.MATCH_PARENT ||
    319                             lp.height == LayoutParams.MATCH_PARENT) {
    320                         mMatchParentChildren.add(child);
    321                     }
    322                 }
    323             }
    324         }
    325 
    326         // Account for padding too
    327         maxWidth += getPaddingLeftWithForeground() + getPaddingRightWithForeground();
    328         maxHeight += getPaddingTopWithForeground() + getPaddingBottomWithForeground();
    329 
    330         // Check against our minimum height and width
    331         maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
    332         maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
    333 
    334         // Check against our foreground's minimum height and width
    335         final Drawable drawable = getForeground();
    336         if (drawable != null) {
    337             maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
    338             maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    339         }
    340 
    341         setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
    342                 resolveSizeAndState(maxHeight, heightMeasureSpec,
    343                         childState << MEASURED_HEIGHT_STATE_SHIFT));
    344 
    345         count = mMatchParentChildren.size();
    346         if (count > 1) {
    347             for (int i = 0; i < count; i++) {
    348                 final View child = mMatchParentChildren.get(i);
    349 
    350                 final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
    351                 int childWidthMeasureSpec;
    352                 int childHeightMeasureSpec;
    353 
    354                 if (lp.width == LayoutParams.MATCH_PARENT) {
    355                     childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() -
    356                             getPaddingLeftWithForeground() - getPaddingRightWithForeground() -
    357                             lp.leftMargin - lp.rightMargin,
    358                             MeasureSpec.EXACTLY);
    359                 } else {
    360                     childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
    361                             getPaddingLeftWithForeground() + getPaddingRightWithForeground() +
    362                             lp.leftMargin + lp.rightMargin,
    363                             lp.width);
    364                 }
    365 
    366                 if (lp.height == LayoutParams.MATCH_PARENT) {
    367                     childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() -
    368                             getPaddingTopWithForeground() - getPaddingBottomWithForeground() -
    369                             lp.topMargin - lp.bottomMargin,
    370                             MeasureSpec.EXACTLY);
    371                 } else {
    372                     childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
    373                             getPaddingTopWithForeground() + getPaddingBottomWithForeground() +
    374                             lp.topMargin + lp.bottomMargin,
    375                             lp.height);
    376                 }
    377 
    378                 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    379             }
    380         }
    381     }
    382 
    383     /**
    384      * {@inheritDoc}
    385      */
    386     @Override
    387     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    388         layoutChildren(left, top, right, bottom, false /* no force left gravity */);
    389     }
    390 
    391     void layoutChildren(int left, int top, int right, int bottom,
    392                                   boolean forceLeftGravity) {
    393         final int count = getChildCount();
    394 
    395         final int parentLeft = getPaddingLeftWithForeground();
    396         final int parentRight = right - left - getPaddingRightWithForeground();
    397 
    398         final int parentTop = getPaddingTopWithForeground();
    399         final int parentBottom = bottom - top - getPaddingBottomWithForeground();
    400 
    401         mForegroundBoundsChanged = true;
    402 
    403         for (int i = 0; i < count; i++) {
    404             final View child = getChildAt(i);
    405             if (child.getVisibility() != GONE) {
    406                 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
    407 
    408                 final int width = child.getMeasuredWidth();
    409                 final int height = child.getMeasuredHeight();
    410 
    411                 int childLeft;
    412                 int childTop;
    413 
    414                 int gravity = lp.gravity;
    415                 if (gravity == -1) {
    416                     gravity = DEFAULT_CHILD_GRAVITY;
    417                 }
    418 
    419                 final int layoutDirection = getLayoutDirection();
    420                 final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
    421                 final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
    422 
    423                 switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
    424                     case Gravity.CENTER_HORIZONTAL:
    425                         childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
    426                         lp.leftMargin - lp.rightMargin;
    427                         break;
    428                     case Gravity.RIGHT:
    429                         if (!forceLeftGravity) {
    430                             childLeft = parentRight - width - lp.rightMargin;
    431                             break;
    432                         }
    433                     case Gravity.LEFT:
    434                     default:
    435                         childLeft = parentLeft + lp.leftMargin;
    436                 }
    437 
    438                 switch (verticalGravity) {
    439                     case Gravity.TOP:
    440                         childTop = parentTop + lp.topMargin;
    441                         break;
    442                     case Gravity.CENTER_VERTICAL:
    443                         childTop = parentTop + (parentBottom - parentTop - height) / 2 +
    444                         lp.topMargin - lp.bottomMargin;
    445                         break;
    446                     case Gravity.BOTTOM:
    447                         childTop = parentBottom - height - lp.bottomMargin;
    448                         break;
    449                     default:
    450                         childTop = parentTop + lp.topMargin;
    451                 }
    452 
    453                 child.layout(childLeft, childTop, childLeft + width, childTop + height);
    454             }
    455         }
    456     }
    457 
    458     /**
    459      * {@inheritDoc}
    460      */
    461     @Override
    462     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    463         super.onSizeChanged(w, h, oldw, oldh);
    464         mForegroundBoundsChanged = true;
    465     }
    466 
    467     /**
    468      * {@inheritDoc}
    469      */
    470     @Override
    471     public void draw(Canvas canvas) {
    472         super.draw(canvas);
    473 
    474         if (mForeground != null) {
    475             final Drawable foreground = mForeground;
    476 
    477             if (mForegroundBoundsChanged) {
    478                 mForegroundBoundsChanged = false;
    479                 final Rect selfBounds = mSelfBounds;
    480                 final Rect overlayBounds = mOverlayBounds;
    481 
    482                 final int w = mRight-mLeft;
    483                 final int h = mBottom-mTop;
    484 
    485                 if (mForegroundInPadding) {
    486                     selfBounds.set(0, 0, w, h);
    487                 } else {
    488                     selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
    489                 }
    490 
    491                 final int layoutDirection = getLayoutDirection();
    492                 Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
    493                         foreground.getIntrinsicHeight(), selfBounds, overlayBounds,
    494                         layoutDirection);
    495                 foreground.setBounds(overlayBounds);
    496             }
    497 
    498             foreground.draw(canvas);
    499         }
    500     }
    501 
    502     /**
    503      * {@inheritDoc}
    504      */
    505     @Override
    506     public boolean gatherTransparentRegion(Region region) {
    507         boolean opaque = super.gatherTransparentRegion(region);
    508         if (region != null && mForeground != null) {
    509             applyDrawableToTransparentRegion(mForeground, region);
    510         }
    511         return opaque;
    512     }
    513 
    514     /**
    515      * Sets whether to consider all children, or just those in
    516      * the VISIBLE or INVISIBLE state, when measuring. Defaults to false.
    517      *
    518      * @param measureAll true to consider children marked GONE, false otherwise.
    519      * Default value is false.
    520      *
    521      * @attr ref android.R.styleable#FrameLayout_measureAllChildren
    522      */
    523     @android.view.RemotableViewMethod
    524     public void setMeasureAllChildren(boolean measureAll) {
    525         mMeasureAllChildren = measureAll;
    526     }
    527 
    528     /**
    529      * Determines whether all children, or just those in the VISIBLE or
    530      * INVISIBLE state, are considered when measuring.
    531      *
    532      * @return Whether all children are considered when measuring.
    533      *
    534      * @deprecated This method is deprecated in favor of
    535      * {@link #getMeasureAllChildren() getMeasureAllChildren()}, which was
    536      * renamed for consistency with
    537      * {@link #setMeasureAllChildren(boolean) setMeasureAllChildren()}.
    538      */
    539     @Deprecated
    540     public boolean getConsiderGoneChildrenWhenMeasuring() {
    541         return getMeasureAllChildren();
    542     }
    543 
    544     /**
    545      * Determines whether all children, or just those in the VISIBLE or
    546      * INVISIBLE state, are considered when measuring.
    547      *
    548      * @return Whether all children are considered when measuring.
    549      */
    550     public boolean getMeasureAllChildren() {
    551         return mMeasureAllChildren;
    552     }
    553 
    554     /**
    555      * {@inheritDoc}
    556      */
    557     @Override
    558     public LayoutParams generateLayoutParams(AttributeSet attrs) {
    559         return new FrameLayout.LayoutParams(getContext(), attrs);
    560     }
    561 
    562     @Override
    563     public boolean shouldDelayChildPressedState() {
    564         return false;
    565     }
    566 
    567     /**
    568      * {@inheritDoc}
    569      */
    570     @Override
    571     protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
    572         return p instanceof LayoutParams;
    573     }
    574 
    575     @Override
    576     protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
    577         return new LayoutParams(p);
    578     }
    579 
    580 
    581     @Override
    582     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    583         super.onInitializeAccessibilityEvent(event);
    584         event.setClassName(FrameLayout.class.getName());
    585     }
    586 
    587     @Override
    588     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    589         super.onInitializeAccessibilityNodeInfo(info);
    590         info.setClassName(FrameLayout.class.getName());
    591     }
    592 
    593     /**
    594      * Per-child layout information for layouts that support margins.
    595      * See {@link android.R.styleable#FrameLayout_Layout FrameLayout Layout Attributes}
    596      * for a list of all child view attributes that this class supports.
    597      *
    598      * @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
    599      */
    600     public static class LayoutParams extends MarginLayoutParams {
    601         /**
    602          * The gravity to apply with the View to which these layout parameters
    603          * are associated.
    604          *
    605          * @see android.view.Gravity
    606          *
    607          * @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
    608          */
    609         public int gravity = -1;
    610 
    611         /**
    612          * {@inheritDoc}
    613          */
    614         public LayoutParams(Context c, AttributeSet attrs) {
    615             super(c, attrs);
    616 
    617             TypedArray a = c.obtainStyledAttributes(attrs, com.android.internal.R.styleable.FrameLayout_Layout);
    618             gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1);
    619             a.recycle();
    620         }
    621 
    622         /**
    623          * {@inheritDoc}
    624          */
    625         public LayoutParams(int width, int height) {
    626             super(width, height);
    627         }
    628 
    629         /**
    630          * Creates a new set of layout parameters with the specified width, height
    631          * and weight.
    632          *
    633          * @param width the width, either {@link #MATCH_PARENT},
    634          *        {@link #WRAP_CONTENT} or a fixed size in pixels
    635          * @param height the height, either {@link #MATCH_PARENT},
    636          *        {@link #WRAP_CONTENT} or a fixed size in pixels
    637          * @param gravity the gravity
    638          *
    639          * @see android.view.Gravity
    640          */
    641         public LayoutParams(int width, int height, int gravity) {
    642             super(width, height);
    643             this.gravity = gravity;
    644         }
    645 
    646         /**
    647          * {@inheritDoc}
    648          */
    649         public LayoutParams(ViewGroup.LayoutParams source) {
    650             super(source);
    651         }
    652 
    653         /**
    654          * {@inheritDoc}
    655          */
    656         public LayoutParams(ViewGroup.MarginLayoutParams source) {
    657             super(source);
    658         }
    659 
    660         /**
    661          * Copy constructor. Clones the width, height, margin values, and
    662          * gravity of the source.
    663          *
    664          * @param source The layout params to copy from.
    665          */
    666         public LayoutParams(LayoutParams source) {
    667             super(source);
    668 
    669             this.gravity = source.gravity;
    670         }
    671     }
    672 }
    673