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