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