blob: 691c941504ccf343fa8f08f254e24ce6e6473191 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.widget;
18
Fabrice Di Megliode35cee2011-06-01 15:13:50 -070019import java.util.ArrayList;
20
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.Context;
22import android.content.res.TypedArray;
23import android.graphics.Canvas;
24import android.graphics.Rect;
25import android.graphics.Region;
26import android.graphics.drawable.Drawable;
27import android.util.AttributeSet;
Fabrice Di Megliode35cee2011-06-01 15:13:50 -070028import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.view.View;
Dianne Hackborn958b9ad2009-03-31 18:00:36 -070030import android.view.ViewDebug;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.view.ViewGroup;
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -080032import android.view.accessibility.AccessibilityEvent;
33import android.view.accessibility.AccessibilityNodeInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.widget.RemoteViews.RemoteView;
35
36
37/**
38 * FrameLayout is designed to block out an area on the screen to display
Scott Main812634c22011-07-27 13:22:35 -070039 * 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()}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 * 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
57public class FrameLayout extends ViewGroup {
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -070058 private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.START;
Romain Guy9c957372011-01-04 17:39:43 -080059
Konstantin Lopyrevbea95162010-08-10 17:02:18 -070060 @ViewDebug.ExportedProperty(category = "measurement")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 boolean mMeasureAllChildren = false;
62
Konstantin Lopyrevbea95162010-08-10 17:02:18 -070063 @ViewDebug.ExportedProperty(category = "drawing")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 private Drawable mForeground;
Konstantin Lopyrevbea95162010-08-10 17:02:18 -070065
66 @ViewDebug.ExportedProperty(category = "padding")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 private int mForegroundPaddingLeft = 0;
Konstantin Lopyrevbea95162010-08-10 17:02:18 -070068
69 @ViewDebug.ExportedProperty(category = "padding")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 private int mForegroundPaddingTop = 0;
Konstantin Lopyrevbea95162010-08-10 17:02:18 -070071
72 @ViewDebug.ExportedProperty(category = "padding")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 private int mForegroundPaddingRight = 0;
Konstantin Lopyrevbea95162010-08-10 17:02:18 -070074
75 @ViewDebug.ExportedProperty(category = "padding")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 private int mForegroundPaddingBottom = 0;
77
78 private final Rect mSelfBounds = new Rect();
79 private final Rect mOverlayBounds = new Rect();
Konstantin Lopyrevbea95162010-08-10 17:02:18 -070080
81 @ViewDebug.ExportedProperty(category = "drawing")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 private int mForegroundGravity = Gravity.FILL;
Karl Rosaen883e7eb2009-03-24 18:55:19 -070083
84 /** {@hide} */
Konstantin Lopyrevbea95162010-08-10 17:02:18 -070085 @ViewDebug.ExportedProperty(category = "drawing")
Karl Rosaen883e7eb2009-03-24 18:55:19 -070086 protected boolean mForegroundInPadding = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087
Dianne Hackborn958b9ad2009-03-31 18:00:36 -070088 boolean mForegroundBoundsChanged = false;
89
Romain Guy9c957372011-01-04 17:39:43 -080090 private final ArrayList<View> mMatchParentChildren = new ArrayList<View>(1);
91
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 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
The Android Open Source Project10592532009-03-18 17:39:46 -0700106 mForegroundGravity = a.getInt(
107 com.android.internal.R.styleable.FrameLayout_foregroundGravity, mForegroundGravity);
108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 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
The Android Open Source Project10592532009-03-18 17:39:46 -0700118 mForegroundInPadding = a.getBoolean(
119 com.android.internal.R.styleable.FrameLayout_foregroundInsidePadding, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120
121 a.recycle();
122 }
123
124 /**
Philip Milne1018fb42012-03-13 12:00:04 -0700125 * 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 /**
Fabrice Di Meglio9e3b0022011-06-06 16:30:29 -0700138 * Describes how the foreground is positioned. Defaults to START and TOP.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 *
140 * @param foregroundGravity See {@link android.view.Gravity}
141 *
Philip Milne1018fb42012-03-13 12:00:04 -0700142 * @see #getForegroundGravity()
143 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 * @attr ref android.R.styleable#FrameLayout_foregroundGravity
145 */
146 @android.view.RemotableViewMethod
147 public void setForegroundGravity(int foregroundGravity) {
148 if (mForegroundGravity != foregroundGravity) {
Fabrice Di Meglio6a036402011-05-23 14:43:23 -0700149 if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
Fabrice Di Meglio9e3b0022011-06-06 16:30:29 -0700150 foregroundGravity |= Gravity.START;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 }
152
153 if ((foregroundGravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
154 foregroundGravity |= Gravity.TOP;
155 }
156
157 mForegroundGravity = foregroundGravity;
The Android Open Source Project10592532009-03-18 17:39:46 -0700158
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 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
Dianne Hackborne2136772010-11-04 15:08:59 -0700187 @Override
188 public void jumpDrawablesToCurrentState() {
189 super.jumpDrawablesToCurrentState();
190 if (mForeground != null) mForeground.jumpToCurrentState();
191 }
192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 /**
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
Romain Guy980a9382010-01-08 15:06:28 -0800206 * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT},
207 * and a height of {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 */
209 @Override
210 protected LayoutParams generateDefaultLayoutParams() {
Romain Guy980a9382010-01-08 15:06:28 -0800211 return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 }
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 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700243 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 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 }
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
Fabrice Di Meglioc4d71222013-06-11 19:13:54 -0700270 int getPaddingLeftWithForeground() {
Michael Jurka02473da2011-09-08 18:26:23 -0700271 return mForegroundInPadding ? Math.max(mPaddingLeft, mForegroundPaddingLeft) :
272 mPaddingLeft + mForegroundPaddingLeft;
273 }
274
Fabrice Di Meglioc4d71222013-06-11 19:13:54 -0700275 int getPaddingRightWithForeground() {
Michael Jurka02473da2011-09-08 18:26:23 -0700276 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 /**
292 * {@inheritDoc}
293 */
294 @Override
295 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Romain Guy9c957372011-01-04 17:39:43 -0800296 int count = getChildCount();
297
298 final boolean measureMatchParentChildren =
299 MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
300 MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
301 mMatchParentChildren.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302
303 int maxHeight = 0;
304 int maxWidth = 0;
Dianne Hackborn189ee182010-12-02 21:48:53 -0800305 int childState = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 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);
Adam Powell2b6be702011-01-08 16:44:07 -0800311 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);
Dianne Hackborn189ee182010-12-02 21:48:53 -0800316 childState = combineMeasuredStates(childState, child.getMeasuredState());
Romain Guy9c957372011-01-04 17:39:43 -0800317 if (measureMatchParentChildren) {
Romain Guy9c957372011-01-04 17:39:43 -0800318 if (lp.width == LayoutParams.MATCH_PARENT ||
319 lp.height == LayoutParams.MATCH_PARENT) {
320 mMatchParentChildren.add(child);
321 }
322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 }
324 }
325
326 // Account for padding too
Michael Jurka02473da2011-09-08 18:26:23 -0700327 maxWidth += getPaddingLeftWithForeground() + getPaddingRightWithForeground();
328 maxHeight += getPaddingTopWithForeground() + getPaddingBottomWithForeground();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329
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
Dianne Hackborn189ee182010-12-02 21:48:53 -0800341 setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
342 resolveSizeAndState(maxHeight, heightMeasureSpec,
Romain Guy9c957372011-01-04 17:39:43 -0800343 childState << MEASURED_HEIGHT_STATE_SHIFT));
344
Romain Guya174d7a2011-01-07 13:27:39 -0800345 count = mMatchParentChildren.size();
346 if (count > 1) {
Romain Guy9c957372011-01-04 17:39:43 -0800347 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;
Romain Guya174d7a2011-01-07 13:27:39 -0800353
Romain Guy9c957372011-01-04 17:39:43 -0800354 if (lp.width == LayoutParams.MATCH_PARENT) {
355 childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() -
Michael Jurka02473da2011-09-08 18:26:23 -0700356 getPaddingLeftWithForeground() - getPaddingRightWithForeground() -
357 lp.leftMargin - lp.rightMargin,
Romain Guy9c957372011-01-04 17:39:43 -0800358 MeasureSpec.EXACTLY);
359 } else {
360 childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
Michael Jurka02473da2011-09-08 18:26:23 -0700361 getPaddingLeftWithForeground() + getPaddingRightWithForeground() +
362 lp.leftMargin + lp.rightMargin,
Romain Guy9c957372011-01-04 17:39:43 -0800363 lp.width);
364 }
365
366 if (lp.height == LayoutParams.MATCH_PARENT) {
367 childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() -
Michael Jurka02473da2011-09-08 18:26:23 -0700368 getPaddingTopWithForeground() - getPaddingBottomWithForeground() -
369 lp.topMargin - lp.bottomMargin,
Romain Guy9c957372011-01-04 17:39:43 -0800370 MeasureSpec.EXACTLY);
371 } else {
Romain Guycf70dcb2011-01-07 11:03:20 -0800372 childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
Michael Jurka02473da2011-09-08 18:26:23 -0700373 getPaddingTopWithForeground() + getPaddingBottomWithForeground() +
374 lp.topMargin + lp.bottomMargin,
Romain Guy9c957372011-01-04 17:39:43 -0800375 lp.height);
376 }
377
378 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
379 }
380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 }
382
383 /**
384 * {@inheritDoc}
385 */
386 @Override
387 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Fabrice Di Meglioc4d71222013-06-11 19:13:54 -0700388 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) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 final int count = getChildCount();
394
Michael Jurka02473da2011-09-08 18:26:23 -0700395 final int parentLeft = getPaddingLeftWithForeground();
396 final int parentRight = right - left - getPaddingRightWithForeground();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397
Michael Jurka02473da2011-09-08 18:26:23 -0700398 final int parentTop = getPaddingTopWithForeground();
399 final int parentBottom = bottom - top - getPaddingBottomWithForeground();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700401 mForegroundBoundsChanged = true;
402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 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
Romain Guy9c957372011-01-04 17:39:43 -0800411 int childLeft;
412 int childTop;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413
Adam Powell5e0ae672010-12-06 21:33:04 -0800414 int gravity = lp.gravity;
415 if (gravity == -1) {
416 gravity = DEFAULT_CHILD_GRAVITY;
417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418
Fabrice Di Meglioe56ffdc2012-09-23 14:51:16 -0700419 final int layoutDirection = getLayoutDirection();
Fabrice Di Meglioc0053222011-06-13 12:16:51 -0700420 final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
Adam Powell5e0ae672010-12-06 21:33:04 -0800421 final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422
Fabrice Di Megliode35cee2011-06-01 15:13:50 -0700423 switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
Adam Powell5e0ae672010-12-06 21:33:04 -0800424 case Gravity.CENTER_HORIZONTAL:
425 childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
426 lp.leftMargin - lp.rightMargin;
427 break;
428 case Gravity.RIGHT:
Fabrice Di Meglioc4d71222013-06-11 19:13:54 -0700429 if (!forceLeftGravity) {
430 childLeft = parentRight - width - lp.rightMargin;
431 break;
432 }
433 case Gravity.LEFT:
Adam Powell5e0ae672010-12-06 21:33:04 -0800434 default:
435 childLeft = parentLeft + lp.leftMargin;
436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437
Adam Powell5e0ae672010-12-06 21:33:04 -0800438 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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 }
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);
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700464 mForegroundBoundsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 }
466
467 /**
468 * {@inheritDoc}
469 */
470 @Override
471 public void draw(Canvas canvas) {
472 super.draw(canvas);
473
474 if (mForeground != null) {
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700475 final Drawable foreground = mForeground;
Romain Guy82f34952009-05-24 18:40:45 -0700476
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700477 if (mForegroundBoundsChanged) {
478 mForegroundBoundsChanged = false;
Romain Guy82f34952009-05-24 18:40:45 -0700479 final Rect selfBounds = mSelfBounds;
480 final Rect overlayBounds = mOverlayBounds;
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700481
Romain Guy82f34952009-05-24 18:40:45 -0700482 final int w = mRight-mLeft;
483 final int h = mBottom-mTop;
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700484
Romain Guy82f34952009-05-24 18:40:45 -0700485 if (mForegroundInPadding) {
486 selfBounds.set(0, 0, w, h);
487 } else {
488 selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700489 }
Romain Guy82f34952009-05-24 18:40:45 -0700490
Fabrice Di Meglioe56ffdc2012-09-23 14:51:16 -0700491 final int layoutDirection = getLayoutDirection();
Romain Guy82f34952009-05-24 18:40:45 -0700492 Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
Fabrice Di Meglioc0053222011-06-13 12:16:51 -0700493 foreground.getIntrinsicHeight(), selfBounds, overlayBounds,
494 layoutDirection);
Romain Guy82f34952009-05-24 18:40:45 -0700495 foreground.setBounds(overlayBounds);
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700496 }
497
498 foreground.draw(canvas);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 }
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 /**
Steve Blockb25825a2011-04-27 14:51:38 +0100515 * Sets whether to consider all children, or just those in
516 * the VISIBLE or INVISIBLE state, when measuring. Defaults to false.
517 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 * @param measureAll true to consider children marked GONE, false otherwise.
519 * Default value is false.
Steve Blockb25825a2011-04-27 14:51:38 +0100520 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 * @attr ref android.R.styleable#FrameLayout_measureAllChildren
522 */
523 @android.view.RemotableViewMethod
524 public void setMeasureAllChildren(boolean measureAll) {
525 mMeasureAllChildren = measureAll;
526 }
Steve Blockb25825a2011-04-27 14:51:38 +0100527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 /**
Steve Blockb25825a2011-04-27 14:51:38 +0100529 * 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()}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 */
Steve Blockb25825a2011-04-27 14:51:38 +0100539 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 public boolean getConsiderGoneChildrenWhenMeasuring() {
Steve Blockb25825a2011-04-27 14:51:38 +0100541 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() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 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
Patrick Dubroye0a799a2011-05-04 16:19:22 -0700562 @Override
563 public boolean shouldDelayChildPressedState() {
564 return false;
565 }
566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 /**
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
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -0800580
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 /**
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.
Romain Guy606e8cc2010-08-17 12:43:05 -0700597 *
598 * @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 */
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
Romain Guy606e8cc2010-08-17 12:43:05 -0700606 *
607 * @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 */
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 *
Romain Guy980a9382010-01-08 15:06:28 -0800633 * @param width the width, either {@link #MATCH_PARENT},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 * {@link #WRAP_CONTENT} or a fixed size in pixels
Romain Guy980a9382010-01-08 15:06:28 -0800635 * @param height the height, either {@link #MATCH_PARENT},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 * {@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}