• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Building Custom Views
2parent.title=Views and Layout
3parent.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>
52The sections below explain how to create custom Views and use them in your application.
53For 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>
68These steps provide a high level overview of
69what you need to know to get started in creating your own
70View 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>
106Fully customized components can be used to create graphical components that
107appear however you wish. Perhaps a graphical VU
108meter that looks like an old analog gauge, or a sing-a-long text view where
109a bouncing ball moves along the words so you can sing along with a karaoke
110machine. Either way, you want something that the built-in components just
111won't do, no matter how you combine them.</p>
112<p>Fortunately, you can easily create components that look and behave in any
113way you like, limited perhaps only by your imagination, the size of the
114screen, and the available processing power (remember that ultimately your
115application might have to run on something with significantly less power
116than 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}
149upon which you can implement anything you want: 2D graphics, other standard or
150custom components, styled text, or anything else you can think of.</p>
151<p><em>Note:</em>
152Except for 3D graphics. If you want to
153use 3D graphics, you must extend {@link android.view.SurfaceView SurfaceView}
154instead of View, and draw from a separate thread. See the
155GLSurfaceViewActivity sample
156for details.</p>
157<p><code>onMeasure()</code> is a little more involved. <code>onMeasure()</code>
158is a critical piece of the rendering contract between your component and its
159container. <code>onMeasure()</code> should be overridden to efficiently and
160accurately report the measurements of its contained parts. This is made
161slightly more complex by the requirements of limits from the parent
162(which are passed in to the <code>onMeasure()</code> method) and by the
163requirement to call the <code>setMeasuredDimension()</code> method with the
164measured width and height once they have been calculated. If you fail to
165call this method from an overridden <code>onMeasure()</code> method, the
166result 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>
201Here'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
313of 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>
315class.</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>
334from the samples. In particular, you can see a mix of both <code>android:</code>
335namespace parameters and custom <code>app:</code> namespace parameters. These
336<code>app:</code> parameters are the custom ones that the LabelView recognizes
337and works with, and are defined in a styleable inner class inside of the
338samples 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
344are looking to put together a reusable component that consists of a group of
345existing controls, then creating a Compound Component (or Compound Control) might
346fit the bill. In a nutshell, this brings together a number of more atomic
347controls (or views) into a logical group of items that can be treated as a
348single thing. For example, a Combo Box can be thought of as a
349combination of a single line EditText field and an adjacent button with an attached
350 PopupList. If you press the button and select
351something from the list, it populates the EditText field, but the user can
352also type something directly into the EditText if they prefer.</p>
353<p>In Android, there are actually two other Views readily available to do
354this: {@link android.widget.Spinner Spinner} and
355{@link android.widget.AutoCompleteTextView AutoCompleteTextView}, but
356regardless, the concept of a Combo Box makes an easy-to-understand
357example.</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
403number 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
433useful in certain circumstances. If there is a component that is already very
434similar to what you want, you can simply extend that component and just
435override the behavior that you want to change. You can do all of the things
436you would do with a fully customized component, but by starting with a more
437specialized class in the View hierarchy, you can also get a lot of behavior for
438free that probably does exactly what you want.</p>
439<p>For example, the SDK includes a <a
440href="{@docRoot}samples/NotePad/index.html">NotePad application</a> in the
441samples. This demonstrates many aspects of using the Android platform, among
442them is extending an EditText View to make a lined notepad. This is not a
443perfect example, and the APIs for doing this might change from this early
444preview, but it does demonstrate the principles.</p>
445<p>If you haven't done so already, import the
446NotePad sample into Eclipse (or
447just look at the source using the link provided). In particular look at the definition of
448<code>MyEditText</code> in the <a
449href="{@docRoot}samples/NotePad/src/com/example/android/notepad/NoteEditor.html">NoteEditor.java</a>
450file.</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&quot;
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
538that's the point &mdash; creating custom components is only as complicated as you
539need it to be.</p>
540<p>A more sophisticated component may override even more <code>on...</code> methods and
541introduce some of its own helper methods, substantially customizing its properties and
542behavior. The only limit is your imagination and what you need the component to
543do.</p>
544
545