blob: b02932838414deff972f8f6dd6c20cdc425302e8 [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
Alan Viverette617feb92013-09-09 18:09:13 -0700100 public FrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
101 this(context, attrs, defStyleAttr, 0);
102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103
Alan Viverette617feb92013-09-09 18:09:13 -0700104 public FrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
105 super(context, attrs, defStyleAttr, defStyleRes);
106
107 final TypedArray a = context.obtainStyledAttributes(
108 attrs, com.android.internal.R.styleable.FrameLayout, defStyleAttr, defStyleRes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109
The Android Open Source Project10592532009-03-18 17:39:46 -0700110 mForegroundGravity = a.getInt(
111 com.android.internal.R.styleable.FrameLayout_foregroundGravity, mForegroundGravity);
112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 final Drawable d = a.getDrawable(com.android.internal.R.styleable.FrameLayout_foreground);
114 if (d != null) {
115 setForeground(d);
116 }
117
118 if (a.getBoolean(com.android.internal.R.styleable.FrameLayout_measureAllChildren, false)) {
119 setMeasureAllChildren(true);
120 }
121
The Android Open Source Project10592532009-03-18 17:39:46 -0700122 mForegroundInPadding = a.getBoolean(
123 com.android.internal.R.styleable.FrameLayout_foregroundInsidePadding, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124
125 a.recycle();
126 }
127
128 /**
Philip Milne1018fb42012-03-13 12:00:04 -0700129 * Describes how the foreground is positioned.
130 *
131 * @return foreground gravity.
132 *
133 * @see #setForegroundGravity(int)
134 *
135 * @attr ref android.R.styleable#FrameLayout_foregroundGravity
136 */
137 public int getForegroundGravity() {
138 return mForegroundGravity;
139 }
140
141 /**
Fabrice Di Meglio9e3b0022011-06-06 16:30:29 -0700142 * Describes how the foreground is positioned. Defaults to START and TOP.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 *
144 * @param foregroundGravity See {@link android.view.Gravity}
145 *
Philip Milne1018fb42012-03-13 12:00:04 -0700146 * @see #getForegroundGravity()
147 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 * @attr ref android.R.styleable#FrameLayout_foregroundGravity
149 */
150 @android.view.RemotableViewMethod
151 public void setForegroundGravity(int foregroundGravity) {
152 if (mForegroundGravity != foregroundGravity) {
Fabrice Di Meglio6a036402011-05-23 14:43:23 -0700153 if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
Fabrice Di Meglio9e3b0022011-06-06 16:30:29 -0700154 foregroundGravity |= Gravity.START;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 }
156
157 if ((foregroundGravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
158 foregroundGravity |= Gravity.TOP;
159 }
160
161 mForegroundGravity = foregroundGravity;
The Android Open Source Project10592532009-03-18 17:39:46 -0700162
163
164 if (mForegroundGravity == Gravity.FILL && mForeground != null) {
165 Rect padding = new Rect();
166 if (mForeground.getPadding(padding)) {
167 mForegroundPaddingLeft = padding.left;
168 mForegroundPaddingTop = padding.top;
169 mForegroundPaddingRight = padding.right;
170 mForegroundPaddingBottom = padding.bottom;
171 }
172 } else {
173 mForegroundPaddingLeft = 0;
174 mForegroundPaddingTop = 0;
175 mForegroundPaddingRight = 0;
176 mForegroundPaddingBottom = 0;
177 }
178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 requestLayout();
180 }
181 }
182
183 /**
184 * {@inheritDoc}
185 */
186 @Override
187 protected boolean verifyDrawable(Drawable who) {
188 return super.verifyDrawable(who) || (who == mForeground);
189 }
190
Dianne Hackborne2136772010-11-04 15:08:59 -0700191 @Override
192 public void jumpDrawablesToCurrentState() {
193 super.jumpDrawablesToCurrentState();
194 if (mForeground != null) mForeground.jumpToCurrentState();
195 }
196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 /**
198 * {@inheritDoc}
199 */
200 @Override
201 protected void drawableStateChanged() {
202 super.drawableStateChanged();
203 if (mForeground != null && mForeground.isStateful()) {
204 mForeground.setState(getDrawableState());
205 }
206 }
207
208 /**
209 * Returns a set of layout parameters with a width of
Romain Guy980a9382010-01-08 15:06:28 -0800210 * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT},
211 * and a height of {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 */
213 @Override
214 protected LayoutParams generateDefaultLayoutParams() {
Romain Guy980a9382010-01-08 15:06:28 -0800215 return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 }
217
218 /**
219 * Supply a Drawable that is to be rendered on top of all of the child
220 * views in the frame layout. Any padding in the Drawable will be taken
221 * into account by ensuring that the children are inset to be placed
222 * inside of the padding area.
223 *
224 * @param drawable The Drawable to be drawn on top of the children.
225 *
226 * @attr ref android.R.styleable#FrameLayout_foreground
227 */
228 public void setForeground(Drawable drawable) {
229 if (mForeground != drawable) {
230 if (mForeground != null) {
231 mForeground.setCallback(null);
232 unscheduleDrawable(mForeground);
233 }
234
235 mForeground = drawable;
236 mForegroundPaddingLeft = 0;
237 mForegroundPaddingTop = 0;
238 mForegroundPaddingRight = 0;
239 mForegroundPaddingBottom = 0;
240
241 if (drawable != null) {
242 setWillNotDraw(false);
243 drawable.setCallback(this);
244 if (drawable.isStateful()) {
245 drawable.setState(getDrawableState());
246 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700247 if (mForegroundGravity == Gravity.FILL) {
248 Rect padding = new Rect();
249 if (drawable.getPadding(padding)) {
250 mForegroundPaddingLeft = padding.left;
251 mForegroundPaddingTop = padding.top;
252 mForegroundPaddingRight = padding.right;
253 mForegroundPaddingBottom = padding.bottom;
254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 }
256 } else {
257 setWillNotDraw(true);
258 }
259 requestLayout();
260 invalidate();
261 }
262 }
263
264 /**
265 * Returns the drawable used as the foreground of this FrameLayout. The
266 * foreground drawable, if non-null, is always drawn on top of the children.
267 *
268 * @return A Drawable or null if no foreground was set.
269 */
270 public Drawable getForeground() {
271 return mForeground;
272 }
273
Fabrice Di Meglioc4d71222013-06-11 19:13:54 -0700274 int getPaddingLeftWithForeground() {
Michael Jurka02473da2011-09-08 18:26:23 -0700275 return mForegroundInPadding ? Math.max(mPaddingLeft, mForegroundPaddingLeft) :
276 mPaddingLeft + mForegroundPaddingLeft;
277 }
278
Fabrice Di Meglioc4d71222013-06-11 19:13:54 -0700279 int getPaddingRightWithForeground() {
Michael Jurka02473da2011-09-08 18:26:23 -0700280 return mForegroundInPadding ? Math.max(mPaddingRight, mForegroundPaddingRight) :
281 mPaddingRight + mForegroundPaddingRight;
282 }
283
284 private int getPaddingTopWithForeground() {
285 return mForegroundInPadding ? Math.max(mPaddingTop, mForegroundPaddingTop) :
286 mPaddingTop + mForegroundPaddingTop;
287 }
288
289 private int getPaddingBottomWithForeground() {
290 return mForegroundInPadding ? Math.max(mPaddingBottom, mForegroundPaddingBottom) :
291 mPaddingBottom + mForegroundPaddingBottom;
292 }
293
294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 /**
296 * {@inheritDoc}
297 */
298 @Override
299 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Romain Guy9c957372011-01-04 17:39:43 -0800300 int count = getChildCount();
301
302 final boolean measureMatchParentChildren =
303 MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
304 MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
305 mMatchParentChildren.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306
307 int maxHeight = 0;
308 int maxWidth = 0;
Dianne Hackborn189ee182010-12-02 21:48:53 -0800309 int childState = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 for (int i = 0; i < count; i++) {
312 final View child = getChildAt(i);
313 if (mMeasureAllChildren || child.getVisibility() != GONE) {
314 measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
Adam Powell2b6be702011-01-08 16:44:07 -0800315 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
316 maxWidth = Math.max(maxWidth,
317 child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
318 maxHeight = Math.max(maxHeight,
319 child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
Dianne Hackborn189ee182010-12-02 21:48:53 -0800320 childState = combineMeasuredStates(childState, child.getMeasuredState());
Romain Guy9c957372011-01-04 17:39:43 -0800321 if (measureMatchParentChildren) {
Romain Guy9c957372011-01-04 17:39:43 -0800322 if (lp.width == LayoutParams.MATCH_PARENT ||
323 lp.height == LayoutParams.MATCH_PARENT) {
324 mMatchParentChildren.add(child);
325 }
326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 }
328 }
329
330 // Account for padding too
Michael Jurka02473da2011-09-08 18:26:23 -0700331 maxWidth += getPaddingLeftWithForeground() + getPaddingRightWithForeground();
332 maxHeight += getPaddingTopWithForeground() + getPaddingBottomWithForeground();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333
334 // Check against our minimum height and width
335 maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
336 maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
337
338 // Check against our foreground's minimum height and width
339 final Drawable drawable = getForeground();
340 if (drawable != null) {
341 maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
342 maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
343 }
344
Dianne Hackborn189ee182010-12-02 21:48:53 -0800345 setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
346 resolveSizeAndState(maxHeight, heightMeasureSpec,
Romain Guy9c957372011-01-04 17:39:43 -0800347 childState << MEASURED_HEIGHT_STATE_SHIFT));
348
Romain Guya174d7a2011-01-07 13:27:39 -0800349 count = mMatchParentChildren.size();
350 if (count > 1) {
Romain Guy9c957372011-01-04 17:39:43 -0800351 for (int i = 0; i < count; i++) {
352 final View child = mMatchParentChildren.get(i);
353
354 final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
355 int childWidthMeasureSpec;
356 int childHeightMeasureSpec;
Romain Guya174d7a2011-01-07 13:27:39 -0800357
Romain Guy9c957372011-01-04 17:39:43 -0800358 if (lp.width == LayoutParams.MATCH_PARENT) {
359 childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() -
Michael Jurka02473da2011-09-08 18:26:23 -0700360 getPaddingLeftWithForeground() - getPaddingRightWithForeground() -
361 lp.leftMargin - lp.rightMargin,
Romain Guy9c957372011-01-04 17:39:43 -0800362 MeasureSpec.EXACTLY);
363 } else {
364 childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
Michael Jurka02473da2011-09-08 18:26:23 -0700365 getPaddingLeftWithForeground() + getPaddingRightWithForeground() +
366 lp.leftMargin + lp.rightMargin,
Romain Guy9c957372011-01-04 17:39:43 -0800367 lp.width);
368 }
369
370 if (lp.height == LayoutParams.MATCH_PARENT) {
371 childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() -
Michael Jurka02473da2011-09-08 18:26:23 -0700372 getPaddingTopWithForeground() - getPaddingBottomWithForeground() -
373 lp.topMargin - lp.bottomMargin,
Romain Guy9c957372011-01-04 17:39:43 -0800374 MeasureSpec.EXACTLY);
375 } else {
Romain Guycf70dcb2011-01-07 11:03:20 -0800376 childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
Michael Jurka02473da2011-09-08 18:26:23 -0700377 getPaddingTopWithForeground() + getPaddingBottomWithForeground() +
378 lp.topMargin + lp.bottomMargin,
Romain Guy9c957372011-01-04 17:39:43 -0800379 lp.height);
380 }
381
382 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
383 }
384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 }
386
387 /**
388 * {@inheritDoc}
389 */
390 @Override
391 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Fabrice Di Meglioc4d71222013-06-11 19:13:54 -0700392 layoutChildren(left, top, right, bottom, false /* no force left gravity */);
393 }
394
395 void layoutChildren(int left, int top, int right, int bottom,
396 boolean forceLeftGravity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 final int count = getChildCount();
398
Michael Jurka02473da2011-09-08 18:26:23 -0700399 final int parentLeft = getPaddingLeftWithForeground();
400 final int parentRight = right - left - getPaddingRightWithForeground();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401
Michael Jurka02473da2011-09-08 18:26:23 -0700402 final int parentTop = getPaddingTopWithForeground();
403 final int parentBottom = bottom - top - getPaddingBottomWithForeground();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700405 mForegroundBoundsChanged = true;
406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 for (int i = 0; i < count; i++) {
408 final View child = getChildAt(i);
409 if (child.getVisibility() != GONE) {
410 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
411
412 final int width = child.getMeasuredWidth();
413 final int height = child.getMeasuredHeight();
414
Romain Guy9c957372011-01-04 17:39:43 -0800415 int childLeft;
416 int childTop;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417
Adam Powell5e0ae672010-12-06 21:33:04 -0800418 int gravity = lp.gravity;
419 if (gravity == -1) {
420 gravity = DEFAULT_CHILD_GRAVITY;
421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422
Fabrice Di Meglioe56ffdc2012-09-23 14:51:16 -0700423 final int layoutDirection = getLayoutDirection();
Fabrice Di Meglioc0053222011-06-13 12:16:51 -0700424 final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
Adam Powell5e0ae672010-12-06 21:33:04 -0800425 final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426
Fabrice Di Megliode35cee2011-06-01 15:13:50 -0700427 switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
Adam Powell5e0ae672010-12-06 21:33:04 -0800428 case Gravity.CENTER_HORIZONTAL:
429 childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
430 lp.leftMargin - lp.rightMargin;
431 break;
432 case Gravity.RIGHT:
Fabrice Di Meglioc4d71222013-06-11 19:13:54 -0700433 if (!forceLeftGravity) {
434 childLeft = parentRight - width - lp.rightMargin;
435 break;
436 }
437 case Gravity.LEFT:
Adam Powell5e0ae672010-12-06 21:33:04 -0800438 default:
439 childLeft = parentLeft + lp.leftMargin;
440 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441
Adam Powell5e0ae672010-12-06 21:33:04 -0800442 switch (verticalGravity) {
443 case Gravity.TOP:
444 childTop = parentTop + lp.topMargin;
445 break;
446 case Gravity.CENTER_VERTICAL:
447 childTop = parentTop + (parentBottom - parentTop - height) / 2 +
448 lp.topMargin - lp.bottomMargin;
449 break;
450 case Gravity.BOTTOM:
451 childTop = parentBottom - height - lp.bottomMargin;
452 break;
453 default:
454 childTop = parentTop + lp.topMargin;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 }
456
457 child.layout(childLeft, childTop, childLeft + width, childTop + height);
458 }
459 }
460 }
461
462 /**
463 * {@inheritDoc}
464 */
465 @Override
466 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
467 super.onSizeChanged(w, h, oldw, oldh);
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700468 mForegroundBoundsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 }
470
471 /**
472 * {@inheritDoc}
473 */
474 @Override
475 public void draw(Canvas canvas) {
476 super.draw(canvas);
477
478 if (mForeground != null) {
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700479 final Drawable foreground = mForeground;
Romain Guy82f34952009-05-24 18:40:45 -0700480
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700481 if (mForegroundBoundsChanged) {
482 mForegroundBoundsChanged = false;
Romain Guy82f34952009-05-24 18:40:45 -0700483 final Rect selfBounds = mSelfBounds;
484 final Rect overlayBounds = mOverlayBounds;
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700485
Romain Guy82f34952009-05-24 18:40:45 -0700486 final int w = mRight-mLeft;
487 final int h = mBottom-mTop;
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700488
Romain Guy82f34952009-05-24 18:40:45 -0700489 if (mForegroundInPadding) {
490 selfBounds.set(0, 0, w, h);
491 } else {
492 selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700493 }
Romain Guy82f34952009-05-24 18:40:45 -0700494
Fabrice Di Meglioe56ffdc2012-09-23 14:51:16 -0700495 final int layoutDirection = getLayoutDirection();
Romain Guy82f34952009-05-24 18:40:45 -0700496 Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
Fabrice Di Meglioc0053222011-06-13 12:16:51 -0700497 foreground.getIntrinsicHeight(), selfBounds, overlayBounds,
498 layoutDirection);
Romain Guy82f34952009-05-24 18:40:45 -0700499 foreground.setBounds(overlayBounds);
Dianne Hackborn958b9ad2009-03-31 18:00:36 -0700500 }
501
502 foreground.draw(canvas);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 }
504 }
505
506 /**
507 * {@inheritDoc}
508 */
509 @Override
510 public boolean gatherTransparentRegion(Region region) {
511 boolean opaque = super.gatherTransparentRegion(region);
512 if (region != null && mForeground != null) {
513 applyDrawableToTransparentRegion(mForeground, region);
514 }
515 return opaque;
516 }
517
518 /**
Steve Blockb25825a2011-04-27 14:51:38 +0100519 * Sets whether to consider all children, or just those in
520 * the VISIBLE or INVISIBLE state, when measuring. Defaults to false.
521 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 * @param measureAll true to consider children marked GONE, false otherwise.
523 * Default value is false.
Steve Blockb25825a2011-04-27 14:51:38 +0100524 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 * @attr ref android.R.styleable#FrameLayout_measureAllChildren
526 */
527 @android.view.RemotableViewMethod
528 public void setMeasureAllChildren(boolean measureAll) {
529 mMeasureAllChildren = measureAll;
530 }
Steve Blockb25825a2011-04-27 14:51:38 +0100531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 /**
Steve Blockb25825a2011-04-27 14:51:38 +0100533 * Determines whether all children, or just those in the VISIBLE or
534 * INVISIBLE state, are considered when measuring.
535 *
536 * @return Whether all children are considered when measuring.
537 *
538 * @deprecated This method is deprecated in favor of
539 * {@link #getMeasureAllChildren() getMeasureAllChildren()}, which was
540 * renamed for consistency with
541 * {@link #setMeasureAllChildren(boolean) setMeasureAllChildren()}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 */
Steve Blockb25825a2011-04-27 14:51:38 +0100543 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 public boolean getConsiderGoneChildrenWhenMeasuring() {
Steve Blockb25825a2011-04-27 14:51:38 +0100545 return getMeasureAllChildren();
546 }
547
548 /**
549 * Determines whether all children, or just those in the VISIBLE or
550 * INVISIBLE state, are considered when measuring.
551 *
552 * @return Whether all children are considered when measuring.
553 */
554 public boolean getMeasureAllChildren() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 return mMeasureAllChildren;
556 }
557
558 /**
559 * {@inheritDoc}
560 */
561 @Override
562 public LayoutParams generateLayoutParams(AttributeSet attrs) {
563 return new FrameLayout.LayoutParams(getContext(), attrs);
564 }
565
Patrick Dubroye0a799a2011-05-04 16:19:22 -0700566 @Override
567 public boolean shouldDelayChildPressedState() {
568 return false;
569 }
570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 /**
572 * {@inheritDoc}
573 */
574 @Override
575 protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
576 return p instanceof LayoutParams;
577 }
578
579 @Override
580 protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
581 return new LayoutParams(p);
582 }
583
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -0800584
585 @Override
586 public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
587 super.onInitializeAccessibilityEvent(event);
588 event.setClassName(FrameLayout.class.getName());
589 }
590
591 @Override
592 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
593 super.onInitializeAccessibilityNodeInfo(info);
594 info.setClassName(FrameLayout.class.getName());
595 }
596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 /**
598 * Per-child layout information for layouts that support margins.
599 * See {@link android.R.styleable#FrameLayout_Layout FrameLayout Layout Attributes}
600 * for a list of all child view attributes that this class supports.
Romain Guy606e8cc2010-08-17 12:43:05 -0700601 *
602 * @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 */
604 public static class LayoutParams extends MarginLayoutParams {
605 /**
606 * The gravity to apply with the View to which these layout parameters
607 * are associated.
608 *
609 * @see android.view.Gravity
Romain Guy606e8cc2010-08-17 12:43:05 -0700610 *
611 * @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 */
613 public int gravity = -1;
614
615 /**
616 * {@inheritDoc}
617 */
618 public LayoutParams(Context c, AttributeSet attrs) {
619 super(c, attrs);
620
621 TypedArray a = c.obtainStyledAttributes(attrs, com.android.internal.R.styleable.FrameLayout_Layout);
622 gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1);
623 a.recycle();
624 }
625
626 /**
627 * {@inheritDoc}
628 */
629 public LayoutParams(int width, int height) {
630 super(width, height);
631 }
632
633 /**
634 * Creates a new set of layout parameters with the specified width, height
635 * and weight.
636 *
Romain Guy980a9382010-01-08 15:06:28 -0800637 * @param width the width, either {@link #MATCH_PARENT},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638 * {@link #WRAP_CONTENT} or a fixed size in pixels
Romain Guy980a9382010-01-08 15:06:28 -0800639 * @param height the height, either {@link #MATCH_PARENT},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 * {@link #WRAP_CONTENT} or a fixed size in pixels
641 * @param gravity the gravity
642 *
643 * @see android.view.Gravity
644 */
645 public LayoutParams(int width, int height, int gravity) {
646 super(width, height);
647 this.gravity = gravity;
648 }
649
650 /**
651 * {@inheritDoc}
652 */
653 public LayoutParams(ViewGroup.LayoutParams source) {
654 super(source);
655 }
656
657 /**
658 * {@inheritDoc}
659 */
660 public LayoutParams(ViewGroup.MarginLayoutParams source) {
661 super(source);
662 }
Alan Viverette0a0e1552013-08-07 13:24:09 -0700663
664 /**
665 * Copy constructor. Clones the width, height, margin values, and
666 * gravity of the source.
667 *
668 * @param source The layout params to copy from.
669 */
670 public LayoutParams(LayoutParams source) {
671 super(source);
672
673 this.gravity = source.gravity;
674 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 }
676}