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 — called widgets and layouts, respectively — 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 — 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 — 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> — 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 <view xmlns:android="http://schemas.android.com/apk/res/android" 509 class="com.android.notepad.NoteEditor$MyEditText" 510 id="@+id/note" 511 android:layout_width="fill_parent" 512 android:layout_height="fill_parent" 513 android:background="@android:drawable/empty" 514 android:padding="10dip" 515 android:scrollbars="vertical" 516 android:fadingEdge="vertical" /> </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 — 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