satya - Tue May 22 2012 13:50:17 GMT-0400 (Eastern Daylight Time)
a presentation at AnDevCon from @chiuki
satya - Tue May 22 2012 13:54:40 GMT-0400 (Eastern Daylight Time)
Here is the deck with out youtube
satya - Tue May 22 2012 15:30:14 GMT-0400 (Eastern Daylight Time)
You can inherit from other views
You can inherit from other views
satya - Tue May 22 2012 15:30:33 GMT-0400 (Eastern Daylight Time)
You need to override
saveInstanceState
restoreInstanceState
satya - Tue May 22 2012 15:30:52 GMT-0400 (Eastern Daylight Time)
You can use xml attributes to define the component in the layout file
You can use xml attributes to define the component in the layout file
satya - Tue May 22 2012 15:32:25 GMT-0400 (Eastern Daylight Time)
Do research on
onLayout
onMeasure
onDraw
dispatchDraw
See what their responsibliities are
satya - Tue May 22 2012 15:33:08 GMT-0400 (Eastern Daylight Time)
Order
measure all children
layout all children
satya - Tue May 22 2012 15:34:55 GMT-0400 (Eastern Daylight Time)
onMeasure: may be
Tell the parent how big you are.
satya - Tue May 22 2012 15:35:33 GMT-0400 (Eastern Daylight Time)
android api setMeasuredDimension
android api setMeasuredDimension
satya - Tue May 22 2012 15:42:48 GMT-0400 (Eastern Daylight Time)
Implementing a custom view doc from android
satya - Tue May 22 2012 15:53:10 GMT-0400 (Eastern Daylight Time)
Here is onMeasure api doc
satya - Tue May 22 2012 15:54:31 GMT-0400 (Eastern Daylight Time)
onMeasure
Subclasses should override onMeasure(int, int) to provide better measurements of their content
satya - Tue May 22 2012 15:57:39 GMT-0400 (Eastern Daylight Time)
Why Measure?
Layout is a two pass process: a measure pass and a layout pass. The measuring pass is implemented in measure(int, int) and is a top-down traversal of the view tree. Each view pushes dimension specifications down the tree during the recursion. At the end of the measure pass, every view has stored its measurements. The second pass happens in layout(int, int, int, int) and is also top-down. During this pass each parent is responsible for positioning all of its children using the sizes computed in the measure pass.
satya - Tue May 22 2012 16:00:10 GMT-0400 (Eastern Daylight Time)
onMeasure may get called multiple times
When a view's measure() method returns, its getMeasuredWidth() and getMeasuredHeight() values must be set, along with those for all of that view's descendants. A view's measured width and measured height values must respect the constraints imposed by the view's parents. This guarantees that at the end of the measure pass, all parents accept all of their children's measurements. A parent view may call measure() more than once on its children. For example, the parent may measure each child once with unspecified dimensions to find out how big they want to be, then call measure() on them again with actual numbers if the sum of all the children's unconstrained sizes is too big or too small.
satya - Tue May 22 2012 16:10:19 GMT-0400 (Eastern Daylight Time)
whats up with LayoutParams class
satya - Tue May 22 2012 16:14:45 GMT-0400 (Eastern Daylight Time)
Understand layout parameters a bit more
satya - Tue May 22 2012 16:15:39 GMT-0400 (Eastern Daylight Time)
A direct document on custom components from Android docs
satya - Tue May 22 2012 16:21:17 GMT-0400 (Eastern Daylight Time)
More on layout params
Every ViewGroup class implements a nested class that extends ViewGroup.LayoutParams. This subclass contains property types that define the size and position for each child view, as appropriate for the view group. As you can see in figure 1, the parent view group defines layout parameters for each child view (including the child view group).
satya - Fri Oct 19 2012 10:02:05 GMT-0400 (Eastern Daylight Time)
Here is what you do in onMeasure: from java2s
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int count = getChildCount();
int maxHeight = 0;
int maxWidth = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}
maxWidth += getPaddingLeft() + getPaddingRight();
maxHeight += getPaddingTop() + getPaddingBottom();
Drawable drawable = getBackground();
if (drawable != null) {
maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
}
setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
resolveSize(maxHeight, heightMeasureSpec));
}
satya - Fri Oct 19 2012 10:04:05 GMT-0400 (Eastern Daylight Time)
This code is taken from a larger example at java2s
satya - Fri Oct 19 2012 10:04:54 GMT-0400 (Eastern Daylight Time)
Methods used above
onMeasure
measureChild
setMeasuredDimension
resolveSize
satya - Fri Oct 19 2012 10:06:27 GMT-0400 (Eastern Daylight Time)
ViewGroup resolveSize
ViewGroup resolveSize
satya - Fri Oct 19 2012 10:22:39 GMT-0400 (Eastern Daylight Time)
How to customize a ViewGroup
How to customize a ViewGroup
satya - Fri Oct 19 2012 13:37:41 GMT-0400 (Eastern Daylight Time)
Key concepts to understand for custom components
merge in layouts
requestLayout
MeasuredSpec
Calling onMeasure of parent for advantage
getMeasuredDimension
Taking into account padding
dispatchDraw
resolveSize
setMeasuredDimension
satya - Fri Oct 19 2012 13:41:09 GMT-0400 (Eastern Daylight Time)
Here is the doc for dispatchDraw
Here is the doc for dispatchDraw
Called by draw to draw the child views. This may be overridden by derived classes to gain control just before its children are drawn (but after its own view has been drawn).
satya - Fri Oct 19 2012 13:48:39 GMT-0400 (Eastern Daylight Time)
android View.java
android View.java
satya - Fri Oct 19 2012 13:51:13 GMT-0400 (Eastern Daylight Time)
Here is one of those links for source code of View.java
Here is one of those links for source code of View.java
I want to see how resolveSize() works
satya - Fri Oct 19 2012 13:51:38 GMT-0400 (Eastern Daylight Time)
Here it is
/**
* Utility to reconcile a desired size with constraints imposed by a MeasureSpec.
* Will take the desired size, unless a different size is imposed by the constraints.
*
* @param size How big the view wants to be
* @param measureSpec Constraints imposed by the parent
* @return The size this view should be.
*/
public static int resolveSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
result = Math.min(size, specSize);
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
satya - Fri Oct 19 2012 13:56:33 GMT-0400 (Eastern Daylight Time)
Here is an example of how base draw works
// skip step 2 & 5 if possible (common case)
final int viewFlags = mViewFlags;
boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
if (!verticalEdges && !horizontalEdges) {
// Step 3, draw the content
mPrivateFlags |= DRAWN;
onDraw(canvas);
// Step 4, draw the children
dispatchDraw(canvas);
// Step 6, draw decorations (scrollbars)
onDrawScrollBars(canvas);
// we're done...
return;
}
satya - Fri Oct 19 2012 13:57:52 GMT-0400 (Eastern Daylight Time)
In fact dispatchDraw is a method of view itself and not ViewGroup
It is basically saying, I am done drawing myself and I might do some housecleaning, do you have something to draw??
satya - Fri Oct 19 2012 14:49:22 GMT-0400 (Eastern Daylight Time)
Here is how the base class measures
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
satya - Fri Oct 19 2012 14:51:22 GMT-0400 (Eastern Daylight Time)
getDeafultSize
public static int getDefaultSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
satya - Fri Oct 19 2012 14:52:55 GMT-0400 (Eastern Daylight Time)
Here is setMinimumWidth
/**
* Sets the minimum width of the view. It is not guaranteed the view will
* be able to achieve this minimum width (for example, if its parent layout
* constrains it with less available width).
*
* @param minWidth The minimum width the view will try to be.
*/
public void setMinimumWidth(int minWidth) {
mMinWidth = minWidth;
}
satya - Fri Oct 19 2012 14:59:39 GMT-0400 (Eastern Daylight Time)
Here is the source code for ViewGroup
satya - Fri Oct 19 2012 15:02:14 GMT-0400 (Eastern Daylight Time)
Here is the dispatchDraw of the ViewGroup
@Override
protected void dispatchDraw(Canvas canvas) {
final int count = mChildrenCount;
final View[] children = mChildren;
int flags = mGroupFlags;
if ((flags & FLAG_RUN_ANIMATION) != 0 && canAnimate()) {
final boolean cache = (mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE;
for (int i = 0; i < count; i++) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
final LayoutParams params = child.getLayoutParams();
attachLayoutAnimationParameters(child, params, i, count);
bindLayoutAnimation(child);
if (cache) {
child.setDrawingCacheEnabled(true);
child.buildDrawingCache();
}
}
}
final LayoutAnimationController controller = mLayoutAnimationController;
if (controller.willOverlap()) {
mGroupFlags |= FLAG_OPTIMIZE_INVALIDATE;
}
controller.start();
mGroupFlags &= ~FLAG_RUN_ANIMATION;
mGroupFlags &= ~FLAG_ANIMATION_DONE;
if (cache) {
mGroupFlags |= FLAG_CHILDREN_DRAWN_WITH_CACHE;
}
if (mAnimationListener != null) {
mAnimationListener.onAnimationStart(controller.getAnimation());
}
}
int saveCount = 0;
final boolean clipToPadding = (flags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
if (clipToPadding) {
saveCount = canvas.save();
final int scrollX = mScrollX;
final int scrollY = mScrollY;
canvas.clipRect(scrollX + mPaddingLeft, scrollY + mPaddingTop,
scrollX + mRight - mLeft - mPaddingRight,
scrollY + mBottom - mTop - mPaddingBottom);
}
mGroupFlags &= ~FLAG_INVALIDATE_REQUIRED;
boolean more = false;
final long drawingTime = getDrawingTime();
if ((flags & FLAG_USE_CHILD_DRAWING_ORDER) == 0) {
for (int i = 0; i < count; i++) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
more |= drawChild(canvas, child, drawingTime);
}
}
} else {
for (int i = 0; i < count; i++) {
final View child = children[getChildDrawingOrder(count, i)];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
more |= drawChild(canvas, child, drawingTime);
}
}
}
// Draw any disappearing views that have animations
if (mDisappearingChildren != null) {
final ArrayList<View> disappearingChildren = mDisappearingChildren;
final int disappearingCount = disappearingChildren.size() - 1;
// Go backwards -- we may delete as animations finish
for (int i = disappearingCount; i >= 0; i--) {
final View child = disappearingChildren.get(i);
more |= drawChild(canvas, child, drawingTime);
}
}
if (clipToPadding) {
canvas.restoreToCount(saveCount);
}
// mGroupFlags might have been updated by drawChild()
flags = mGroupFlags;
if ((flags & FLAG_INVALIDATE_REQUIRED) == FLAG_INVALIDATE_REQUIRED) {
invalidate();
}
if ((flags & FLAG_ANIMATION_DONE) == 0 && (flags & FLAG_NOTIFY_ANIMATION_LISTENER) == 0 &&
mLayoutAnimationController.isDone() && !more) {
// We want to erase the drawing cache and notify the listener after the
// next frame is drawn because one extra invalidate() is caused by
// drawChild() after the animation is over
mGroupFlags |= FLAG_NOTIFY_ANIMATION_LISTENER;
final Runnable end = new Runnable() {
public void run() {
notifyAnimationListener();
}
};
post(end);
}
}
satya - Fri Oct 19 2012 15:15:36 GMT-0400 (Eastern Daylight Time)
android layouts merge element
android layouts merge element
satya - Fri Oct 19 2012 15:27:08 GMT-0400 (Eastern Daylight Time)
View constructor inflating a layout
View constructor inflating a layout
satya - Fri Oct 19 2012 15:28:07 GMT-0400 (Eastern Daylight Time)
a merge can be used as a root xml element in reusable layout files
include tag
self inflating view
satya - Fri Oct 19 2012 15:30:19 GMT-0400 (Eastern Daylight Time)
Example
a.xml
************
<merge>
(bunch of controls)
</merge>
b.xml
*****************
<LinearLayout>
(bunch of controls)
<include a.xml>
(other bunch)
</LinearLayout>
Doing it this way you avoid creating another linear layout just because you don't have a root node you can use to share!!
satya - Fri Oct 19 2012 16:19:57 GMT-0400 (Eastern Daylight Time)
android requestLayout
android requestLayout
satya - Fri Oct 19 2012 19:04:23 GMT-0400 (Eastern Daylight Time)
what is the difference between invalidate and requestlayout in android
what is the difference between invalidate and requestlayout in android
Search for: what is the difference between invalidate and requestlayout in android
satya - Fri Oct 19 2012 22:12:40 GMT-0400 (Eastern Daylight Time)
So here is the difference between requestLayout and invalidate in android
if you merely change the drawing and keep the relative postions of everything on the screen the same then invalidate() will call the onDraw() methods. The layout step that figures out the measurements and placements will not be called. (That is my initial understading. This is so early looking at this I could be wrong. But it makes sense).
If you call requestLayout() then the layouts and positions are recalculated. This seem to imply a redraw. If so I am not sure why folks are doing this
requestLayout() invalidate()
If requestLayout also triggers redraw why call invalidate?
satya - Sat Oct 20 2012 09:52:51 GMT-0400 (Eastern Daylight Time)
Do I need both requestLayout, forceLayout and invalidate?
Do I need both requestLayout, forceLayout and invalidate?
Search for: Do I need both requestLayout, forceLayout and invalidate?
satya - Sat Oct 20 2012 09:56:01 GMT-0400 (Eastern Daylight Time)
An interesting anti-pattern when these are called from onSizeChanged
An interesting anti-pattern when these are called from onSizeChanged
satya - Sat Oct 20 2012 10:01:35 GMT-0400 (Eastern Daylight Time)
Read this first: How android draws views
satya - Sat Oct 20 2012 10:38:30 GMT-0400 (Eastern Daylight Time)
Here are some view drawing predicates
Views only in the invalid region are redrawn
You can force a view to draw (only) using invalidate
parents are drawn first
Measure Phases
Phase 1: find out how big each view wants to be (UNSPECIFIED)
Phase 2: impose real sizes (through EXACT or AT MOST)
each view sets the setMeasuredWidth
satya - Sat Oct 20 2012 11:00:58 GMT-0400 (Eastern Daylight Time)
android onLayout
android onLayout
satya - Sat Oct 20 2012 11:13:45 GMT-0400 (Eastern Daylight Time)
onSizeChanged and onLayout
onSizeChanged and onLayout
satya - Sat Oct 20 2012 11:14:46 GMT-0400 (Eastern Daylight Time)
Google doc on the layouts from the masters: Romain, Chet
Google doc on the layouts from the masters: Romain, Chet
you will need a google account password like your gmail to access this!
satya - Sat Oct 20 2012 11:27:15 GMT-0400 (Eastern Daylight Time)
Difference bettwen layout, onlayout and onsizechanged
Layout phase ends up calling a view that the layout has changed by calling "layout". A view will then call onSizeChanged so that the derived view can note its coordinates. This is a self method invocation.
However the onLayout() is not meant for itself but for others, like children or tell the world out there "hey! I am a view. I have just adjusted my sizes through onSizechanged(). I am telling you that. Before I go back and return from the layout phase see if you have anything else to do in this callback from me called "onLayout()".
satya - Sat Oct 20 2012 11:37:53 GMT-0400 (Eastern Daylight Time)
Here is Chet, Romain's presentations on pareleys.com
satya - Sat Oct 20 2012 11:45:09 GMT-0400 (Eastern Daylight Time)
Ahah! use generateDefaultLayoutParams()
Ahah! use generateDefaultLayoutParams()
satya - Sat Oct 20 2012 11:46:12 GMT-0400 (Eastern Daylight Time)
In android dp pixel what is the standard size?
In android dp pixel what is the standard size?
satya - Sat Oct 20 2012 11:47:39 GMT-0400 (Eastern Daylight Time)
match_parent means just the size of the parent
it can still cross parent boundaries if it is laid out offset
satya - Sat Oct 20 2012 11:48:46 GMT-0400 (Eastern Daylight Time)
we know that: margins are outside a view
we know that: margins are outside a view
satya - Sat Oct 20 2012 11:49:35 GMT-0400 (Eastern Daylight Time)
left and top includes the padding
left and top includes the padding
satya - Sat Oct 20 2012 11:50:12 GMT-0400 (Eastern Daylight Time)
gravity example
bottom|left
satya - Sat Oct 20 2012 11:51:05 GMT-0400 (Eastern Daylight Time)
Avoid deep nested linear layouts
Avoid deep nested linear layouts
satya - Sat Oct 20 2012 11:54:13 GMT-0400 (Eastern Daylight Time)
width/height set to zero and use weights
width/height set to zero and use weights
satya - Sat Oct 20 2012 12:00:08 GMT-0400 (Eastern Daylight Time)
TableLayout is an optimized linearlayout
TableLayout is an optimized linearlayout
satya - Sat Oct 20 2012 12:14:15 GMT-0400 (Eastern Daylight Time)
what do you do in setText on a text view?
I know you would call requestLayout. But do you also call invalidate? See the source code of TextView to figure this out!
satya - Sat Oct 20 2012 12:17:37 GMT-0400 (Eastern Daylight Time)
Exactly
When you specify a view to be exactly 10 pixels in the xml files then you will get a measure pass that tells you to use 10 pixels EXACT!
satya - Sat Oct 20 2012 12:18:14 GMT-0400 (Eastern Daylight Time)
AT MOST
when you say match parent, you will get at most the width of the parent!!
satya - Sat Oct 20 2012 12:20:18 GMT-0400 (Eastern Daylight Time)
Don't directly use child.measure() instead use ViewGroup.measureChild()
which will take into account whether to use exactly or at most etc...
satya - Sat Oct 20 2012 12:39:01 GMT-0400 (Eastern Daylight Time)
Code for implementing a layoutparams is pretty identical to what the layouts does in the framework
Code for implementing a layoutparams is pretty identical to what the layouts does in the framework
satya - Sat Oct 20 2012 12:50:32 GMT-0400 (Eastern Daylight Time)
Android Flow layout
Android Flow layout
satya - Sat Oct 20 2012 13:50:10 GMT-0400 (Eastern Daylight Time)
android TextView.java
android TextView.java
satya - Sat Oct 20 2012 14:00:04 GMT-0400 (Eastern Daylight Time)
Here is requestLayout of a View method
/**
* Call this when something has changed which has invalidated the
* layout of this view. This will schedule a layout pass of the view
* tree.
*/
public void requestLayout() {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.REQUEST_LAYOUT);
}
mPrivateFlags |= FORCE_LAYOUT;
if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
}
}
satya - Sat Oct 20 2012 14:03:06 GMT-0400 (Eastern Daylight Time)
requestLayout
requestLayout
Search Google for: requestLayout
Search Android Developers Group for: requestLayout
Search Android Beginers Group for: requestLayout
satya - Sat Oct 20 2012 14:03:18 GMT-0400 (Eastern Daylight Time)
requestLayout Romain
requestLayout Romain
satya - Sat Oct 20 2012 14:09:19 GMT-0400 (Eastern Daylight Time)
ViewGroup is a ViewParent!!
ViewGroup is a ViewParent!!
satya - Sat Oct 20 2012 14:41:20 GMT-0400 (Eastern Daylight Time)
How does invalidate trigger a draw in Android
How does invalidate trigger a draw in Android
satya - Sat Oct 20 2012 14:59:53 GMT-0400 (Eastern Daylight Time)
android ViewRoot.java
android ViewRoot.java
satya - Sat Oct 20 2012 15:01:45 GMT-0400 (Eastern Daylight Time)
Here is the source code for ViewRoot.java
satya - Sat Oct 20 2012 15:02:03 GMT-0400 (Eastern Daylight Time)
Here is how invalidate will end up traversing
Here is how invalidate will end up traversing
satya - Sat Oct 20 2012 15:05:06 GMT-0400 (Eastern Daylight Time)
GOOOOOOT ITTTTTTTTT
//In ViewRoot!!
public void requestLayout() {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
satya - Sat Oct 20 2012 15:18:16 GMT-0400 (Eastern Daylight Time)
ViewRoot performTraversals
ViewRoot performTraversals
satya - Thu Oct 25 2012 16:16:57 GMT-0400 (Eastern Daylight Time)
android when do you use forceLayout?
android when do you use forceLayout?
satya - Thu Oct 25 2012 16:24:34 GMT-0400 (Eastern Daylight Time)
forcelayout romain
forcelayout romain
satya - Thu Oct 25 2012 16:24:43 GMT-0400 (Eastern Daylight Time)
forcelayout dianne
forcelayout dianne
satya - Thu Oct 25 2012 16:34:30 GMT-0400 (Eastern Daylight Time)
Here is one place it is used cleverly
public class CallLogListItemView extends LinearLayout {
public CallLogListItemView(Context context) {
super(context);
}
public CallLogListItemView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CallLogListItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void requestLayout() {
// We will assume that once measured this will not need to resize
// itself, so there is no need to pass the layout request to the parent
// view (ListView).
forceLayout();
}
}
satya - Thu Oct 25 2012 16:41:04 GMT-0400 (Eastern Daylight Time)
Here is what table layout does
/**
* {@inheritDoc}
*/
@Override
public void requestLayout() {
if (mInitialized) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).forceLayout();
}
}
super.requestLayout();
}
satya - Thu Oct 25 2012 16:43:05 GMT-0400 (Eastern Daylight Time)
If a view doesn't have children
it has nothing else to request layout but her parent. However if you happen to have children they need to be told as well.
Bottom line is measure will not work and will not call onMeasure if the layout flag is not set.
satya - Thu Oct 25 2012 16:59:41 GMT-0400 (Eastern Daylight Time)
Really what happens when you DONT call forcelayout on a view
If this view didn't cause the requestLayout, and is a sibling or a child of the view that caused it, then its layout flag is empty. This means it will return the old measures. If I have a view group that I delete a view, that doesn't change the measurement requirements of its siblings.
However if it does then the view group needs to "touch" the child views with forced layout and they will measure when the pass comes along!!!
satya - Thu Oct 25 2012 21:06:59 GMT-0400 (Eastern Daylight Time)
What is the difference between forceLayout() and requestLayout()
It is easier to tell you what forceLayout() is first. It is like a "touch" command in build environments. Usually when a file doesn't change the build dependencies will ignore it. So you force that file to be compiled by "touch"ing and thereby updating its time stamp.
So when you forceLayout() on a view you are marking that view (only that). If a view is not marked then its onMeasure() will not be called. You can see this in the measure() method of the view. It checks to see if this view is marked.
The behavior of requestLayout() is slightly different. a requestlayout touches the current view just like forceLayout() but also walks up the chain touching every parent of this view until it reaches ViewRoot. ViewRoot overrides this method and schedules a layout pass. Because it is just a schedule to run it doesnt start the layout pass right away. It will wait for the main thread to complete its chores and attend the message queue.
Still, explain to me when I use forceLayout!! I understand the requestLayout because I end up scheduling a pass. What am I doing with forceLayout? Obviously if you are calling a requestLayout on a view there is no point in calling forceLayout on that view. What is "force" anyway?
Do you recall, that a "force" is like a "touch" for build!! So you are "forcing" the file to compile.
When a view gets its requestLayout called, all its siblings are untouched. They don't have this flag setup. Or if the view that is touched is a viewgroup (like when you delete a view or add a view) the viewgroup doesn't need to calculate teh sizes of the its children because their sizes haven't changed. No point in calling their onMeasure. But if for some reason if the view group decides that these children needs to be measured, it will call forceLayout on each of them followed by measure() which now correctly calls onmeasure().
what happens the very first time?? who touched all views to begin with. I reason that (I haven't verified this yet) the views start out with this flag being set!! Let me see I will check in a minute and report again.
satya - Thu Oct 25 2012 21:34:05 GMT-0400 (Eastern Daylight Time)
Ok, I concede my hunch is not right but close
the initial request to layout a new view happens when the view is added to a parent like a viewgroup!! So there is that mystery set aside.