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     private int getPaddingLeftWithForeground() {
    271         return mForegroundInPadding ? Math.max(mPaddingLeft, mForegroundPaddingLeft) :
    272             mPaddingLeft + mForegroundPaddingLeft;
    273     }
    274 
    275     private 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         final int count = getChildCount();
    389 
    390         final int parentLeft = getPaddingLeftWithForeground();
    391         final int parentRight = right - left - getPaddingRightWithForeground();
    392 
    393         final int parentTop = getPaddingTopWithForeground();
    394         final int parentBottom = bottom - top - getPaddingBottomWithForeground();
    395 
    396         mForegroundBoundsChanged = true;
    397 
    398         for (int i = 0; i < count; i++) {
    399             final View child = getChildAt(i);
    400             if (child.getVisibility() != GONE) {
    401                 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
    402 
    403                 final int width = child.getMeasuredWidth();
    404                 final int height = child.getMeasuredHeight();
    405 
    406                 int childLeft;
    407                 int childTop;
    408 
    409                 int gravity = lp.gravity;
    410                 if (gravity == -1) {
    411                     gravity = DEFAULT_CHILD_GRAVITY;
    412                 }
    413 
    414                 final int layoutDirection = getLayoutDirection();
    415                 final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
    416                 final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
    417 
    418                 switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
    419                     case Gravity.LEFT:
    420                         childLeft = parentLeft + lp.leftMargin;
    421                         break;
    422                     case Gravity.CENTER_HORIZONTAL:
    423                         childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
    424                         lp.leftMargin - lp.rightMargin;
    425                         break;
    426                     case Gravity.RIGHT:
    427                         childLeft = parentRight - width - lp.rightMargin;
    428                         break;
    429                     default:
    430                         childLeft = parentLeft + lp.leftMargin;
    431                 }
    432 
    433                 switch (verticalGravity) {
    434                     case Gravity.TOP:
    435                         childTop = parentTop + lp.topMargin;
    436                         break;
    437                     case Gravity.CENTER_VERTICAL:
    438                         childTop = parentTop + (parentBottom - parentTop - height) / 2 +
    439                         lp.topMargin - lp.bottomMargin;
    440                         break;
    441                     case Gravity.BOTTOM:
    442                         childTop = parentBottom - height - lp.bottomMargin;
    443                         break;
    444                     default:
    445                         childTop = parentTop + lp.topMargin;
    446                 }
    447 
    448                 child.layout(childLeft, childTop, childLeft + width, childTop + height);
    449             }
    450         }
    451     }
    452 
    453     /**
    454      * {@inheritDoc}
    455      */
    456     @Override
    457     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    458         super.onSizeChanged(w, h, oldw, oldh);
    459         mForegroundBoundsChanged = true;
    460     }
    461 
    462     /**
    463      * {@inheritDoc}
    464      */
    465     @Override
    466     public void draw(Canvas canvas) {
    467         super.draw(canvas);
    468 
    469         if (mForeground != null) {
    470             final Drawable foreground = mForeground;
    471 
    472             if (mForegroundBoundsChanged) {
    473                 mForegroundBoundsChanged = false;
    474                 final Rect selfBounds = mSelfBounds;
    475                 final Rect overlayBounds = mOverlayBounds;
    476 
    477                 final int w = mRight-mLeft;
    478                 final int h = mBottom-mTop;
    479 
    480                 if (mForegroundInPadding) {
    481                     selfBounds.set(0, 0, w, h);
    482                 } else {
    483                     selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
    484                 }
    485 
    486                 final int layoutDirection = getLayoutDirection();
    487                 Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
    488                         foreground.getIntrinsicHeight(), selfBounds, overlayBounds,
    489                         layoutDirection);
    490                 foreground.setBounds(overlayBounds);
    491             }
    492 
    493             foreground.draw(canvas);
    494         }
    495     }
    496 
    497     /**
    498      * {@inheritDoc}
    499      */
    500     @Override
    501     public boolean gatherTransparentRegion(Region region) {
    502         boolean opaque = super.gatherTransparentRegion(region);
    503         if (region != null && mForeground != null) {
    504             applyDrawableToTransparentRegion(mForeground, region);
    505         }
    506         return opaque;
    507     }
    508 
    509     /**
    510      * Sets whether to consider all children, or just those in
    511      * the VISIBLE or INVISIBLE state, when measuring. Defaults to false.
    512      *
    513      * @param measureAll true to consider children marked GONE, false otherwise.
    514      * Default value is false.
    515      *
    516      * @attr ref android.R.styleable#FrameLayout_measureAllChildren
    517      */
    518     @android.view.RemotableViewMethod
    519     public void setMeasureAllChildren(boolean measureAll) {
    520         mMeasureAllChildren = measureAll;
    521     }
    522 
    523     /**
    524      * Determines whether all children, or just those in the VISIBLE or
    525      * INVISIBLE state, are considered when measuring.
    526      *
    527      * @return Whether all children are considered when measuring.
    528      *
    529      * @deprecated This method is deprecated in favor of
    530      * {@link #getMeasureAllChildren() getMeasureAllChildren()}, which was
    531      * renamed for consistency with
    532      * {@link #setMeasureAllChildren(boolean) setMeasureAllChildren()}.
    533      */
    534     @Deprecated
    535     public boolean getConsiderGoneChildrenWhenMeasuring() {
    536         return getMeasureAllChildren();
    537     }
    538 
    539     /**
    540      * Determines whether all children, or just those in the VISIBLE or
    541      * INVISIBLE state, are considered when measuring.
    542      *
    543      * @return Whether all children are considered when measuring.
    544      */
    545     public boolean getMeasureAllChildren() {
    546         return mMeasureAllChildren;
    547     }
    548 
    549     /**
    550      * {@inheritDoc}
    551      */
    552     @Override
    553     public LayoutParams generateLayoutParams(AttributeSet attrs) {
    554         return new FrameLayout.LayoutParams(getContext(), attrs);
    555     }
    556 
    557     @Override
    558     public boolean shouldDelayChildPressedState() {
    559         return false;
    560     }
    561 
    562     /**
    563      * {@inheritDoc}
    564      */
    565     @Override
    566     protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
    567         return p instanceof LayoutParams;
    568     }
    569 
    570     @Override
    571     protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
    572         return new LayoutParams(p);
    573     }
    574 
    575 
    576     @Override
    577     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    578         super.onInitializeAccessibilityEvent(event);
    579         event.setClassName(FrameLayout.class.getName());
    580     }
    581 
    582     @Override
    583     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    584         super.onInitializeAccessibilityNodeInfo(info);
    585         info.setClassName(FrameLayout.class.getName());
    586     }
    587 
    588     /**
    589      * Per-child layout information for layouts that support margins.
    590      * See {@link android.R.styleable#FrameLayout_Layout FrameLayout Layout Attributes}
    591      * for a list of all child view attributes that this class supports.
    592      *
    593      * @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
    594      */
    595     public static class LayoutParams extends MarginLayoutParams {
    596         /**
    597          * The gravity to apply with the View to which these layout parameters
    598          * are associated.
    599          *
    600          * @see android.view.Gravity
    601          *
    602          * @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
    603          */
    604         public int gravity = -1;
    605 
    606         /**
    607          * {@inheritDoc}
    608          */
    609         public LayoutParams(Context c, AttributeSet attrs) {
    610             super(c, attrs);
    611 
    612             TypedArray a = c.obtainStyledAttributes(attrs, com.android.internal.R.styleable.FrameLayout_Layout);
    613             gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1);
    614             a.recycle();
    615         }
    616 
    617         /**
    618          * {@inheritDoc}
    619          */
    620         public LayoutParams(int width, int height) {
    621             super(width, height);
    622         }
    623 
    624         /**
    625          * Creates a new set of layout parameters with the specified width, height
    626          * and weight.
    627          *
    628          * @param width the width, either {@link #MATCH_PARENT},
    629          *        {@link #WRAP_CONTENT} or a fixed size in pixels
    630          * @param height the height, either {@link #MATCH_PARENT},
    631          *        {@link #WRAP_CONTENT} or a fixed size in pixels
    632          * @param gravity the gravity
    633          *
    634          * @see android.view.Gravity
    635          */
    636         public LayoutParams(int width, int height, int gravity) {
    637             super(width, height);
    638             this.gravity = gravity;
    639         }
    640 
    641         /**
    642          * {@inheritDoc}
    643          */
    644         public LayoutParams(ViewGroup.LayoutParams source) {
    645             super(source);
    646         }
    647 
    648         /**
    649          * {@inheritDoc}
    650          */
    651         public LayoutParams(ViewGroup.MarginLayoutParams source) {
    652             super(source);
    653         }
    654     }
    655 }
    656