satya - Tue May 22 2012 13:50:17 GMT-0400 (Eastern Daylight Time)

a presentation at AnDevCon from @chiuki

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

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

Search for: android api setMeasuredDimension

satya - Tue May 22 2012 15:42:48 GMT-0400 (Eastern Daylight Time)

Implementing a custom view doc from android

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

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

whats up with LayoutParams class

satya - Tue May 22 2012 16:14:45 GMT-0400 (Eastern Daylight Time)

Understand layout parameters a bit more

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

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

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

Search for: 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

Search for: 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

Search for: 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

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

Search for: 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

Search for: 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

Search for: 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

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

Search for: android onLayout

satya - Sat Oct 20 2012 11:13:45 GMT-0400 (Eastern Daylight Time)

onSizeChanged and onLayout

onSizeChanged and onLayout

Search for: 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

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?

Search for: 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

Search for: Android Flow layout

satya - Sat Oct 20 2012 13:50:10 GMT-0400 (Eastern Daylight Time)

android TextView.java

android TextView.java

Search for: 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

Search Google Code for: requestLayout

Search Android Issues Database for: requestLayout

satya - Sat Oct 20 2012 14:03:18 GMT-0400 (Eastern Daylight Time)

requestLayout Romain

requestLayout Romain

Search for: 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

Search for: 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

Search for: android ViewRoot.java

satya - Sat Oct 20 2012 15:01:45 GMT-0400 (Eastern Daylight Time)

Here is the source code for ViewRoot.java

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

Search for: 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?

Search for: android when do you use forceLayout?

satya - Thu Oct 25 2012 16:24:34 GMT-0400 (Eastern Daylight Time)

forcelayout romain

forcelayout romain

Search for: forcelayout romain

satya - Thu Oct 25 2012 16:24:43 GMT-0400 (Eastern Daylight Time)

forcelayout dianne

forcelayout dianne

Search for: 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.