Home | History | Annotate | Download | only in views
      1 page.title=Building Custom Views
      2 parent.title=Views and Layout
      3 parent.link=index.html
      4 @jd:body
      5 
      6 <p>Android offers a sophisticated and powerful componentized model for building your UI, based on the fundamental building block classes {@link android.view.View} and {@link android.view.ViewGroup}. To start with, the platform includes a variety of prebuilt View and ViewGroup subclasses &mdash; called widgets and layouts, respectively &mdash; that you can use to construct your UI. The widgets and layouts are fully implemented and handle all of their own measuring and drawing, so you can use them right away. You can make new types of UI elements simply by nesting and grouping the widgets and layouts. Using widgets and layouts is the recommended approach to building a UI for your applications.</p>
      7 
      8 <p>A partial list of available widgets includes {@link android.widget.Button Button}, 
      9 {@link android.widget.TextView TextView}, 
     10 {@link android.widget.EditText EditText}, 
     11 {@link android.widget.ListView ListView},
     12 {@link android.widget.CheckBox CheckBox}, 
     13 {@link android.widget.RadioButton RadioButton}, 
     14 {@link android.widget.Gallery Gallery}, 
     15 {@link android.widget.Spinner Spinner}, and the more special-purpose 
     16 {@link android.widget.AutoCompleteTextView AutoCompleteTextView}, 
     17 {@link android.widget.ImageSwitcher ImageSwitcher}, and
     18 {@link android.widget.TextSwitcher TextSwitcher}. </p>
     19 
     20 <p>Among the layouts available are {@link android.widget.LinearLayout LinearLayout}, 
     21 {@link android.widget.FrameLayout FrameLayout}, {@link android.widget.AbsoluteLayout AbsoluteLayout}, and others. For more examples, see <a href="layout">Common Layout Objects</a>.</p>
     22 
     23 <p>If none of the prebuilt widgets or layouts meets your needs, you can also create your own View subclass, such as a layout group or compound control. If you only need to make small adjustments to an existing widget or layout, you can simply subclass the widget or layout and override its methods.
     24 </p>
     25 
     26 <p>Creating your own View subclasses gives you precise control over the appearance and function of a screen element. To give an idea of the control you get with custom views, here are some examples of what you could do with them:</p>
     27  
     28 <ul>
     29   <li>
     30     You could create a completely custom-rendered View type, for example a "volume
     31     control" knob rendered using 2D graphics, and which resembles an
     32     analog electronic control.
     33   </li>
     34   <li>
     35     You could combine a group of View components into a new single component, perhaps
     36     to make something like a ComboBox (a combination of popup list and free
     37     entry text field), a dual-pane selector control (a left and right pane
     38     with a list in each where you can re-assign which item is in which
     39     list), and so on.
     40   </li>
     41   <li>
     42     You could override the way that an EditText component is rendered on the screen
     43     (the <a href="{@docRoot}resources/samples/NotePad/">Notepad sample</a> uses this to good effect, 
     44     to create a lined-notepad page).
     45   </li>
     46   <li>
     47     You could capture other events like key presses and handle them in some custom
     48     way (such as for a game).
     49   </li>
     50 </ul>
     51 <p>
     52 The sections below explain how to create custom Views and use them in your application. 
     53 For detailed reference information, see the {@link android.view.View} class. </p>
     54 
     55 <p>This document covers the following:</p>
     56 <ol class="toc">
     57   <li><a href="#basic">The Basic Approach</a></li>
     58   <li><a href="#custom">Fully Customized Views</a></li>
     59   <li><a href="#customexample">Customized View Example</a></li> 
     60   <li><a href="#compound">Compound Controls</a></li>
     61   <li><a href="#tweaking">Modifying an Existing Component Type</a></li>
     62 </ol>
     63 
     64 <a name="basic"></a> 
     65 <h2>The Basic Approach
     66 </h2>
     67 <p>
     68 These steps provide a high level overview of
     69 what you need to know to get started in creating your own
     70 View components:</p>
     71  
     72 <ol>
     73   <li>
     74     Extend an existing {@link android.view.View View} class or subclass 
     75 	with your own class.
     76   </li>
     77   <li>
     78     Override some of the methods from the superclass: the superclass methods 
     79     to override start with '<code>on</code>', for
     80     example, {@link android.view.View#onDraw onDraw()}, 
     81     {@link android.view.View#onMeasure onMeasure()}, and 
     82     {@link android.view.View#onKeyDown onKeyDown()}.
     83     <ul>
     84       <li>
     85         This is similar to the <code>on...</code> events in {@link android.app.Activity
     86 	    Activity} or {@link android.app.ListActivity ListActivity}
     87         that you override for life cycle and other functionality hooks.
     88       </li>
     89     </ul>
     90   <li>
     91     Use your new extension class: once completed, your new extension class 
     92     can be used in place of the view upon which it was based, but now with the new 
     93     functionality.
     94   </li>
     95 </ol>  
     96 <p class="note"><strong>Tip:</strong>
     97     Extension classes can be defined as inner classes inside the activities
     98     that use them. This is useful because it controls access to them but
     99     isn't necessary (perhaps you want to create a new public View for
    100     wider use in your application).
    101 </p>
    102 
    103 <a name="custom"></a> 
    104 <h2>Fully Customized Components</h2>
    105 <p>
    106 Fully customized components can be used to create graphical components that
    107 appear however you wish. Perhaps a graphical VU
    108 meter that looks like an old analog gauge, or a sing-a-long text view where
    109 a bouncing ball moves along the words so you can sing along with a karaoke
    110 machine. Either way, you want something that the built-in components just
    111 won't do, no matter how you combine them.</p>
    112 <p>Fortunately, you can easily create components that look and behave in any
    113 way you like, limited perhaps only by your imagination, the size of the
    114 screen, and the available processing power (remember that ultimately your
    115 application might have to run on something with significantly less power
    116 than your desktop workstation).</p>
    117 <p>To create a fully customized component:</p> 
    118 <ol>
    119   <li>
    120     The most generic view you can extend is, unsurprisingly, {@link
    121     android.view.View View}, so you will usually start by extending this to
    122     create your new super component.
    123   </li>
    124   <li>
    125     You can supply a constructor which can
    126     take attributes and parameters from the XML, and you can also consume
    127     your own such attributes and parameters (perhaps the color and range of
    128     the VU meter, or the width and damping of the needle, etc.)
    129   </li>
    130   <li>
    131     You will probably want to create your own event listeners,
    132     property accessors and modifiers, and possibly more sophisticated
    133     behavior in your component class as well.
    134   </li>
    135   <li>
    136     You will almost certainly want to override <code>onMeasure()</code> and
    137     are also likely to need to override <code>onDraw()</code> if you want
    138     the component to show something. While both have default behavior,
    139     the default <code>onDraw()</code> will do nothing, and the default
    140     <code>onMeasure()</code> will always set a size of 100x100 &mdash; which is
    141     probably not what you want.
    142   </li>
    143   <li>
    144     Other <code>on...</code> methods may also be overridden as required.
    145   </li>
    146 </ol>
    147 <h4><code>onDraw()</code> and <code>onMeasure()</code></h4>
    148 <p><code>onDraw()</code> delivers you a {@link android.graphics.Canvas Canvas}
    149 upon which you can implement anything you want: 2D graphics, other standard or
    150 custom components, styled text, or anything else you can think of.</p>
    151 <p><em>Note:</em>
    152 Except for 3D graphics. If you want to
    153 use 3D graphics, you must extend {@link android.view.SurfaceView SurfaceView}
    154 instead of View, and draw from a separate thread. See the
    155 GLSurfaceViewActivity sample
    156 for details.</p>
    157 <p><code>onMeasure()</code> is a little more involved. <code>onMeasure()</code>
    158 is a critical piece of the rendering contract between your component and its
    159 container. <code>onMeasure()</code> should be overridden to efficiently and
    160 accurately report the measurements of its contained parts. This is made
    161 slightly more complex by the requirements of limits from the parent
    162 (which are passed in to the <code>onMeasure()</code> method) and by the
    163 requirement to call the <code>setMeasuredDimension()</code> method with the
    164 measured width and height once they have been calculated. If you fail to
    165 call this method from an overridden <code>onMeasure()</code> method, the 
    166 result will be an exception at measurement time.</p>
    167 <p>At a high level, implementing <code>onMeasure()</code> looks something 
    168  like this:</p>
    169  
    170 <ol>
    171   <li>
    172     The overridden <code>onMeasure()</code> method is called with width and
    173     height measure specifications (<code>widthMeasureSpec</code> and
    174     <code>heightMeasureSpec</code> parameters, both are integer codes
    175     representing dimensions) which should be treated as requirements for
    176     the restrictions on the width and height measurements you should produce. A
    177     full reference to the kind of restrictions these specifications can require
    178     can be found in the reference documentation under {@link
    179     android.view.View#onMeasure View.onMeasure(int, int)} (this reference
    180     documentation does a pretty good job of explaining the whole measurement
    181     operation as well).
    182   </li>
    183   <li>
    184     Your component's <code>onMeasure()</code> method should calculate a
    185     measurement width and height which will be required to render the
    186     component. It should try to stay within the specifications passed in,
    187     although it can choose to exceed them (in this case, the parent can
    188     choose what to do, including clipping, scrolling, throwing an exception, 
    189     or asking the <code>onMeasure()</code> to try again, perhaps with
    190     different measurement specifications).
    191   </li>
    192   <li>
    193     Once the width and height are calculated, the <code>setMeasuredDimension(int
    194     width, int height)</code> method must be called with the calculated
    195     measurements. Failure to do this will result in an exception being
    196     thrown.
    197   </li>
    198 </ol>
    199 
    200 <p>
    201 Here's a summary of some of the other standard methods that the framework calls on views:
    202 </p>
    203 <table border="2" width="85%" align="center" cellpadding="5">
    204        <thead>
    205            <tr><th>Category</th> <th>Methods</th> <th>Description</th></tr>
    206        </thead>
    207        
    208        <tbody>
    209        <tr>
    210            <td rowspan="2">Creation</td>
    211            <td>Constructors</td>
    212            <td>There is a form of the constructor that are called when the view
    213            is created from code and a form that is called when the view is
    214            inflated from a layout file. The second form should parse and apply
    215            any attributes defined in the layout file.
    216            </td>
    217        </tr>
    218        <tr>
    219            <td><code>{@link android.view.View#onFinishInflate()}</code></td>
    220            <td>Called after a view and all of its children has been inflated
    221            from XML.</td>
    222        </tr>
    223        
    224        <tr>
    225            <td rowspan="3">Layout</td>
    226            <td><code>{@link  android.view.View#onMeasure}</code></td>
    227            <td>Called to determine the size requirements for this view and all
    228            of its children.
    229            </td>
    230        </tr>
    231        <tr>
    232            <td><code>{@link  android.view.View#onLayout}</code></td>
    233            <td>Called when this view should assign a size and position to all
    234            of its children.
    235            </td>
    236        </tr>
    237        <tr>
    238            <td><code>{@link  android.view.View#onSizeChanged}</code></td>
    239            <td>Called when the size of this view has changed.
    240            </td>
    241        </tr>
    242        
    243        <tr>
    244            <td>Drawing</td>
    245            <td><code>{@link  android.view.View#onDraw}</code></td>
    246            <td>Called when the view should render its content.
    247            </td>
    248        </tr>
    249   
    250        <tr>
    251            <td rowspan="4">Event processing</td>
    252            <td><code>{@link  android.view.View#onKeyDown}</code></td>
    253            <td>Called when a new key event occurs.
    254            </td>
    255        </tr>
    256        <tr>
    257            <td><code>{@link  android.view.View#onKeyUp}</code></td>
    258            <td>Called when a key up event occurs.
    259            </td>
    260        </tr>   
    261        <tr>
    262            <td><code>{@link  android.view.View#onTrackballEvent}</code></td>
    263            <td>Called when a trackball motion event occurs.
    264            </td>
    265        </tr>  
    266        <tr>
    267            <td><code>{@link  android.view.View#onTouchEvent}</code></td>
    268            <td>Called when a touch screen motion event occurs.
    269            </td>
    270        </tr>  
    271        
    272        <tr>
    273            <td rowspan="2">Focus</td>
    274            <td><code>{@link  android.view.View#onFocusChanged}</code></td>
    275            <td>Called when the view gains or loses focus.
    276            </td>
    277        </tr>
    278        
    279        <tr>
    280            <td><code>{@link  android.view.View#onWindowFocusChanged}</code></td>
    281            <td>Called when the window containing the view gains or loses focus.
    282            </td>
    283        </tr>
    284        
    285        <tr>
    286            <td rowspan="3">Attaching</td>
    287            <td><code>{@link  android.view.View#onAttachedToWindow()}</code></td>
    288            <td>Called when the view is attached to a window.
    289            </td>
    290        </tr>
    291   
    292        <tr>
    293            <td><code>{@link  android.view.View#onDetachedFromWindow}</code></td>
    294            <td>Called when the view is detached from its window.
    295            </td>
    296        </tr>     
    297   
    298        <tr>
    299            <td><code>{@link  android.view.View#onWindowVisibilityChanged}</code></td>
    300            <td>Called when the visibility of the window containing the view
    301            has changed.
    302            </td>
    303        </tr>     
    304        </tbody>
    305        
    306    </table>
    307 
    308 
    309 <a name="customexample"></a>
    310 <h3>A Custom View Example</h3>
    311 <p>The CustomView sample in the 
    312 <a href="{@docRoot}samples/ApiDemos/index.html">API Demos</a> provides an example
    313 of a customized View. The custom View is defined in the
    314 <a href="{@docRoot}samples/ApiDemos/src/com/example/android/apis/view/LabelView.html">LabelView</a>
    315 class.</p>
    316 <p>The LabelView sample demonstrates a number of different aspects of custom components:</p>
    317 <ul>
    318   <li>Extending the View class for a completely custom component.</li>
    319   <li>Parameterized constructor that takes the view inflation parameters
    320   (parameters defined in the XML). Some of these are passed through to the
    321   View superclass, but more importantly, there are some custom attributes defined
    322   and used for LabelView.</li>
    323   <li>Standard public methods of the type you would expect to see for a label
    324   component, for example <code>setText()</code>, <code>setTextSize()</code>,
    325   <code>setTextColor()</code> and so on.</li>
    326   <li>An overridden <code>onMeasure</code> method to determine and set the
    327   rendering size of the component. (Note that in LabelView, the real work is done
    328   by a private <code>measureWidth()</code> method.)</li>
    329   <li>An overridden <code>onDraw()</code> method to draw the label onto the
    330   provided canvas.</li>
    331 </ul>
    332 <p>You can see some sample usages of the LabelView custom View in
    333 <a href="{@docRoot}samples/ApiDemos/res/layout/custom_view_1.html">custom_view_1.xml</a>
    334 from the samples. In particular, you can see a mix of both <code>android:</code>
    335 namespace parameters and custom <code>app:</code> namespace parameters. These
    336 <code>app:</code> parameters are the custom ones that the LabelView recognizes
    337 and works with, and are defined in a styleable inner class inside of the
    338 samples R resources definition class.</p>
    339 
    340 <a name="compound"></a>  
    341 <h2>Compound Controls
    342 </h2>
    343 <p>If you don't want to create a completely customized component, but instead
    344 are looking to put together a reusable component that consists of a group of
    345 existing controls, then creating a Compound Component (or Compound Control) might
    346 fit the bill. In a nutshell, this brings together a number of more atomic
    347 controls (or views) into a logical group of items that can be treated as a
    348 single thing. For example, a Combo Box can be thought of as a
    349 combination of a single line EditText field and an adjacent button with an attached
    350  PopupList. If you press the button and select
    351 something from the list, it populates the EditText field, but the user can
    352 also type something directly into the EditText if they prefer.</p>
    353 <p>In Android, there are actually two other Views readily available to do
    354 this: {@link android.widget.Spinner Spinner} and 
    355 {@link android.widget.AutoCompleteTextView AutoCompleteTextView}, but 
    356 regardless, the concept of a Combo Box makes an easy-to-understand 
    357 example.</p>
    358 <p>To create a compound component:</p>
    359 <ol>
    360   <li>
    361     The usual starting point is a Layout of some kind, so create a class
    362     that extends a Layout. Perhaps in the case of a Combo box we might use
    363     a LinearLayout with horizontal orientation. Remember that other layouts
    364     can be nested inside, so the compound component can be arbitrarily
    365     complex and structured. Note that just like with an Activity, you can
    366     use either the declarative (XML-based) approach to creating the
    367     contained components, or you can nest them programmatically from your
    368     code.
    369   </li>
    370   <li>
    371     In the constructor for the new class, take whatever parameters the
    372     superclass expects, and pass them through to the superclass constructor
    373     first. Then you can set up the other views to use within your new
    374     component; this is where you would create the EditText field and the
    375     PopupList. Note that you also might introduce your own attributes and
    376     parameters into the XML that can be pulled out and used by your
    377     constructor.
    378   </li>
    379   <li>
    380     You can also create listeners for events that your contained views might
    381     generate, for example, a listener method for the List Item Click Listener
    382     to update the contents of the EditText if a list selection is made.
    383   </li>
    384   <li>
    385     You might also create your own properties with accessors and modifiers,
    386     for example, allow the EditText value to be set initially in the
    387     component and query for its contents when needed.
    388   </li>
    389   <li>
    390     In the case of extending a Layout, you don't need to override the
    391     <code>onDraw()</code> and <code>onMeasure()</code> methods since the
    392     layout will have default behavior that will likely work just fine. However, 
    393     you can still override them if you need to.
    394   </li>
    395   <li>
    396     You might override other <code>on...</code> methods, like
    397     <code>onKeyDown()</code>, to perhaps choose certain default values from
    398     the popup list of a combo box when a certain key is pressed.
    399   </li>
    400 </ol>
    401 <p>
    402  To summarize, the use of a Layout as the basis for a Custom Control has a
    403 number of advantages, including:</p>
    404  
    405 <ul>
    406   <li>
    407     You can specify the layout using the declarative XML files just like
    408     with an activity screen, or you can create views programmatically and
    409     nest them into the layout from your code.
    410   </li>
    411   <li>
    412     The <code>onDraw()</code> and <code>onMeasure()</code> methods (plus
    413     most of the other <code>on...</code> methods) will likely have suitable behavior so
    414     you don't have to override them.
    415   </li>
    416   <li>
    417     In the end, you can very quickly construct arbitrarily complex compound
    418     views and re-use them as if they were a single component.
    419   </li>
    420 </ul>
    421 <h4>Examples of Compound Controls</h4>
    422 <p>In the API Demos project
    423  that comes with the SDK, there are two List
    424  examples &mdash; Example 4 and Example 6 under Views/Lists demonstrate a
    425  SpeechView which extends LinearLayout to make a component for displaying
    426  Speech quotes. The corresponding classes in the sample code are
    427  <code>List4.java</code> and <code>List6.java</code>.</p>
    428  
    429 <a name="tweaking"></a>  
    430 <h2>Modifying an Existing View Type
    431 </h2>
    432 <p>There is an even easier option for creating a custom View which is
    433 useful in certain circumstances. If there is a component that is already very
    434 similar to what you want, you can simply extend that component and just
    435 override the behavior that you want to change. You can do all of the things
    436 you would do with a fully customized component, but by starting with a more
    437 specialized class in the View hierarchy, you can also get a lot of behavior for
    438 free that probably does exactly what you want.</p>
    439 <p>For example, the SDK includes a <a
    440 href="{@docRoot}samples/NotePad/index.html">NotePad application</a> in the
    441 samples. This demonstrates many aspects of using the Android platform, among
    442 them is extending an EditText View to make a lined notepad. This is not a
    443 perfect example, and the APIs for doing this might change from this early
    444 preview, but it does demonstrate the principles.</p>
    445 <p>If you haven't done so already, import the 
    446 NotePad sample into Eclipse (or
    447 just look at the source using the link provided). In particular look at the definition of
    448 <code>MyEditText</code> in the <a
    449 href="{@docRoot}samples/NotePad/src/com/example/android/notepad/NoteEditor.html">NoteEditor.java</a>
    450 file.</p>
    451 <p>Some points to note here</p>
    452 <ol>
    453   <li>
    454     <strong>The Definition</strong>
    455     <p>The class is defined with the following line:</p>
    456      <code>public static class MyEditText extends EditText</code><br><br>
    457      
    458     <ul>
    459       <li>
    460         It is defined as an inner class within the <code>NoteEditor</code>
    461         activity, but it is public so that it could be accessed as
    462         <code>NoteEditor.MyEditText</code> from outside of the <code>NoteEditor</code>
    463         class if desired.
    464       </li>
    465       <li>
    466         It is <code>static</code>, meaning it does not generate the so-called
    467         "synthetic methods" that allow it to access data from the parent
    468         class, which in turn means that it really behaves as a separate
    469         class rather than something strongly related to <code>NoteEditor</code>.
    470         This is a cleaner way to create inner classes if they do not need
    471         access to state from the outer class, keeps the generated class
    472         small, and allows it to be used easily from other classes.
    473       </li>
    474       <li>
    475         It extends <code>EditText</code>, which is the View we have chosen to
    476         customize in this case. When we are finished, the new class will be
    477         able to substitute for a normal <code>EditText</code> view.<br>
    478         <br>
    479       </li>
    480     </ul>
    481   </li>
    482   <li>
    483     <strong>Class Initialization</strong>
    484     <p>As always, the super is called first. Furthermore, 
    485     this is not a default constructor, but a parameterized one. The
    486     EditText is created with these parameters when it is inflated from an
    487     XML layout file, thus, our constructor needs to both take them and pass them
    488     to the superclass constructor as well.</p>
    489   </li>
    490   <li>
    491     <strong>Overridden Methods</strong>
    492     <p>In this example, there is only one method to be overridden: 
    493     <code>onDraw()</code> &mdash; but there could easily be others needed when you
    494     create your own custom components.</p>
    495     <p>For the NotePad sample, overriding the <code>onDraw()</code> method allows
    496     us to paint the blue lines on the <code>EditText</code> view canvas (the
    497     canvas is passed into the overridden <code>onDraw()</code> method). The
    498     super.onDraw() method is called before the method ends. The
    499     superclass method should be invoked, but in this case, we do it at the
    500     end after we have painted the lines we want to include.</p>
    501   <li>
    502     <strong>Use the Custom Component</strong>
    503     <p>We now have our custom component, but how can we use it? In the
    504     NotePad example, the custom component is used directly from the
    505     declarative layout, so take a look at <code>note_editor.xml</code> in the
    506     <code>res/layout</code> folder.</p>
    507     <pre>
    508 &lt;view xmlns:android=&quot;http://schemas.android.com/apk/res/android"; 
    509   class=&quot;com.android.notepad.NoteEditor$MyEditText&quot; 
    510   id=&quot;&#64;+id/note&quot;
    511   android:layout_width=&quot;fill_parent&quot;
    512   android:layout_height=&quot;fill_parent&quot;
    513   android:background=&quot;&#64;android:drawable/empty&quot;
    514   android:padding=&quot;10dip&quot;
    515   android:scrollbars=&quot;vertical&quot;
    516   android:fadingEdge=&quot;vertical&quot; /&gt; </pre>
    517      
    518     <ul>
    519       <li>
    520         The custom component is created as a generic view in the XML, and
    521         the class is specified using the full package. Note also that the
    522         inner class we defined is referenced using the
    523         <code>NoteEditor$MyEditText</code> notation which is a standard way to
    524         refer to inner classes in the Java programming language.
    525       </li>
    526       <li>
    527         The other attributes and parameters in the definition are the ones
    528         passed into the custom component constructor, and then passed
    529         through to the EditText constructor, so they are the same
    530         parameters that you would use for an EditText view. Note that it is
    531         possible to add your own parameters as well, and we will touch on
    532         this again below.
    533       </li>
    534     </ul>
    535   </li>
    536 </ol>
    537 <p>And that's all there is to it. Admittedly this is a simple case, but
    538 that's the point &mdash; creating custom components is only as complicated as you
    539 need it to be.</p>
    540 <p>A more sophisticated component may override even more <code>on...</code> methods and
    541 introduce some of its own helper methods, substantially customizing its properties and
    542 behavior. The only limit is your imagination and what you need the component to
    543 do.</p>
    544 
    545