Home | History | Annotate | Download | only in ui
      1 page.title=How Android Draws Views
      2 parent.title=User Interface
      3 parent.link=index.html
      4 @jd:body
      5 
      6 
      7 <p>When an {@link android.app.Activity} receives focus, it will be requested to 
      8 draw its layout.
      9 The Android framework will handle the procedure for drawing, but the 
     10 {@link android.app.Activity} must provide
     11 the root node of its layout hierarchy.</p>
     12 
     13 <p>Drawing begins with the root node of the layout. It is requested to measure and 
     14 draw the layout tree. Drawing is handled by walking the tree and rendering each 
     15 {@link android.view.View} that intersects the invalid region. In turn, each 
     16 {@link android.view.ViewGroup} is responsible for requesting
     17 each of its children to be drawn 
     18 (with the {@link android.view.View#draw(Canvas) draw()} method) 
     19 and each {@link android.view.View} is responsible for drawing itself.
     20  Because the tree is traversed in-order,
     21    this means that parents will be drawn before (i.e., behind) their children, with
     22    siblings drawn in the order they appear in the tree.
     23    </p>
     24 
     25 <div class="sidebox-wrapper">
     26 <div class="sidebox">
     27   <p>The framework will not draw {@link android.view.View} objects that are not 
     28 in the invalid region, and also 
     29    will take care of drawing the {@link android.view.View} background for you.</p>
     30    <p>You can force a {@link android.view.View} to draw, by calling 
     31 {@link android.view.View#invalidate()}.
     32    </p>
     33 </div>
     34 </div>
     35 
     36 <p>
     37    Drawing the layout is a two pass process: a measure pass and a layout pass. 
     38 The measuring pass is implemented in {@link android.view.View#measure(int, int)} 
     39 and is a top-down traversal of the {@link android.view.View} tree. Each {@link android.view.View} 
     40 pushes dimension specifications down the tree
     41    during the recursion. At the end of the measure pass, every 
     42 {@link android.view.View} has stored
     43    its measurements. The second pass happens in
     44    {@link android.view.View#layout(int,int,int,int)} and is also top-down. During
     45    this pass each parent is responsible for positioning all of its children
     46    using the sizes computed in the measure pass.
     47    </p>
     48    
     49    <p>
     50    When a {@link android.view.View} object's 
     51 {@link android.view.View#measure(int, int) measure()} method 
     52 returns, its {@link android.view.View#getMeasuredWidth()} and
     53    {@link android.view.View#getMeasuredHeight()} values must be set, along 
     54    with those for all of that {@link android.view.View} object's descendants. 
     55 A {@link android.view.View} object's measured width and 
     56 measured height values must respect the constraints imposed by the 
     57 {@link android.view.View} object's parents. This guarantees
     58    that at the end of the measure pass, all parents accept all of their
     59    children's measurements. A parent {@link android.view.View} may call 
     60 {@link android.view.View#measure(int, int) measure()} more than once on
     61    its children. For example, the parent may measure each child once with
     62    unspecified dimensions to find out how big they want to be, then call
     63    {@link android.view.View#measure(int, int) measure()} on them again with 
     64 actual numbers if the sum of all the children's
     65    unconstrained sizes is too big or too small (that is, if the children 
     66 don't agree among themselves
     67   as to how much space they each get, the parent will intervene and set 
     68 the rules on the second pass).
     69    </p>
     70    
     71 <div class="sidebox-wrapper">
     72 <div class="sidebox"><p>
     73    To initiate a layout, call {@link android.view.View#requestLayout}. 
     74 This method is typically
     75    called by a {@link android.view.View} on itself 
     76 when it believes that is can no longer fit within
     77    its current bounds.</p>
     78 </div>
     79 </div>
     80 
     81    <p>
     82    The measure pass uses two classes to communicate dimensions. The
     83    {@link android.view.ViewGroup.LayoutParams} class is used by 
     84 {@link android.view.View} objects to tell their parents how they
     85    want to be measured and positioned. The base 
     86 {@link android.view.ViewGroup.LayoutParams}  class just
     87    describes how big the {@link android.view.View} wants to be for both 
     88 width and height. For each
     89    dimension, it can specify one of:</p>
     90    <ul>
     91     <li> an exact number
     92     <li>{@link android.view.ViewGroup.LayoutParams#MATCH_PARENT MATCH_PARENT}, 
     93 which means the {@link android.view.View} wants to be as big as its parent
     94     (minus padding)</li>
     95     <li>{@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT WRAP_CONTENT}, 
     96 which means that the {@link android.view.View} wants to be just big enough to
     97     enclose its content (plus padding).</li>
     98    </ul>
     99   <p>There are subclasses of {@link android.view.ViewGroup.LayoutParams} for 
    100 different subclasses of {@link android.view.ViewGroup}.
    101    For example, {@link android.widget.RelativeLayout} has its own subclass of 
    102 {@link android.view.ViewGroup.LayoutParams}, which includes
    103    the ability to center child {@link android.view.View} objects 
    104 horizontally and vertically.
    105    </p>
    106    
    107    <p>
    108    {@link android.view.View.MeasureSpec MeasureSpec} objects are used to push 
    109 requirements down the tree from parent to
    110    child. A {@link android.view.View.MeasureSpec MeasureSpec} can be in one of 
    111 three modes:</p>
    112    <ul>
    113     <li>{@link android.view.View.MeasureSpec#UNSPECIFIED UNSPECIFIED}: This is 
    114 used by a parent to determine the desired dimension
    115     of a child {@link android.view.View}. For example, a 
    116 {@link android.widget.LinearLayout} may call 
    117 {@link android.view.View#measure(int, int) measure()} on its child
    118     with the height set to {@link android.view.View.MeasureSpec#UNSPECIFIED UNSPECIFIED} 
    119 and a width of {@link android.view.View.MeasureSpec#EXACTLY EXACTLY} 240 to 
    120 find out how tall the child {@link android.view.View} wants to be given a 
    121 width of 240 pixels.</li>
    122     <li>{@link android.view.View.MeasureSpec#EXACTLY EXACTLY}: This is used 
    123 by the parent to impose an exact size on the
    124     child. The child must use this size, and guarantee that all of its
    125     descendants will fit within this size.</li>
    126     <li>{@link android.view.View.MeasureSpec#AT_MOST AT MOST}: This is used by 
    127 the parent to impose a maximum size on the
    128     child. The child must guarantee that it and all of its descendants will fit
    129     within this size.</li>
    130    </ul>
    131    
    132 
    133 
    134