Home | History | Annotate | Download | only in graphics
      1 page.title=Canvas and Drawables
      2 parent.title=Graphics
      3 parent.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="#draw-with-canvas">Draw with a Canvas</a>
     11     <ol>
     12       <li><a href="#on-view">On a View</a></li>
     13       <li><a href="#on-surfaceview">On a SurfaceView</a></li>
     14     </ol>
     15     </li>
     16     <li><a href="#drawables">Drawables</a>
     17         <ol>
     18           <li><a href="#drawables-from-images">Creating from resource images</a></li>
     19           <li><a href="#drawables-from-xml">Creating from resource XML</a></li>
     20         </ol>
     21     </li>
     22     <li><a href="#shape-drawable">Shape Drawable</a></li>
     23     <li><a href="#nine-patch">Nine-patch</a></li>
     24   </ol>
     25 
     26   <h2>See also</h2>
     27   <ol>
     28     <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL with the Framework
     29 APIs</a></li>
     30     <li><a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a></li>
     31   </ol>
     32   </div>
     33 </div>
     34 
     35 <p>The Android framework APIs provides a set 2D drawing APIs that allow you to render your own
     36 custom graphics onto a canvas or to modify existing Views to customize their look and feel.
     37 When drawing 2D graphics, you'll typically do so in one of two ways:</p>
     38 
     39 <ol type="a">
     40   <li>Draw your graphics or animations into a View object from your layout. In this manner,
     41   the drawing of your graphics is handled by the system's
     42   normal View hierarchy drawing process &mdash; you simply define the graphics to go inside the View.</li>
     43   <li>Draw your graphics directly to a Canvas. This way, you personally call the appropriate class's
     44   {@link android.view.View#onDraw onDraw()} method (passing it your Canvas), or one of the Canvas
     45 <code>draw...()</code> methods (like
     46   <code>{@link android.graphics.Canvas#drawPicture(Picture,Rect) drawPicture()}</code>). In doing so, you are also in
     47   control of any animation.</li>
     48 </ol>
     49 
     50 <p>Option "a," drawing to a View, is your best choice when you want to draw simple graphics that do not
     51 need to change dynamically and are not part of a performance-intensive game. For example, you should
     52 draw your graphics into a View when you want to display a static graphic or predefined animation, within
     53 an otherwise static application. Read <a href="#drawables">Drawables</a> for more information.</li>
     54 </p>
     55 
     56 <p>Option "b," drawing to a Canvas, is better when your application needs to regularly re-draw itself.
     57 Applications such as video games should be drawing to the Canvas on its own. However, there's more than
     58 one way to do this:</p>
     59 
     60 <ul>
     61   <li>In the same thread as your UI Activity, wherein you create a custom View component in
     62   your layout, call <code>{@link android.view.View#invalidate()}</code> and then handle the
     63   <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> callback.</li>
     64   <li>Or, in a separate thread, wherein you manage a {@link android.view.SurfaceView} and
     65   perform draws to the Canvas as fast as your thread is capable
     66   (you do not need to request <code>invalidate()</code>).</li>
     67 </ul>
     68 
     69 <h2 id="draw-with-canvas">Draw with a Canvas</h2>
     70 
     71 <p>When you're writing an application in which you would like to perform specialized drawing
     72 and/or control the animation of graphics,
     73 you should do so by drawing through a {@link android.graphics.Canvas}. A Canvas works for you as
     74 a pretense, or interface, to the actual surface upon which your graphics will be drawn &mdash; it
     75 holds all of your "draw" calls. Via the Canvas, your drawing is actually performed upon an
     76 underlying {@link android.graphics.Bitmap}, which is placed into the window.</p>
     77 
     78 <p>In the event that you're drawing within the <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code>
     79 callback method, the Canvas is provided for you and you need only place your drawing calls upon it.
     80 You can also acquire a Canvas from <code>{@link android.view.SurfaceHolder#lockCanvas() SurfaceHolder.lockCanvas()}</code>,
     81 when dealing with a SurfaceView object. (Both of these scenarios are discussed in the following sections.)
     82 However, if you need to create a new Canvas, then you must define the {@link android.graphics.Bitmap}
     83 upon which drawing will actually be performed. The Bitmap is always required for a Canvas. You can set up
     84 a new Canvas like this:</p>
     85 <pre>
     86 Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
     87 Canvas c = new Canvas(b);
     88 </pre>
     89 
     90 <p>Now your Canvas will draw onto the defined Bitmap. After drawing upon it with the Canvas, you can then carry your
     91 Bitmap to another Canvas with one of the <code>{@link android.graphics.Canvas#drawBitmap(Bitmap,Matrix,Paint)
     92 Canvas.drawBitmap(Bitmap,...)}</code> methods. It's recommended that you ultimately draw your final
     93 graphics through a Canvas offered to you
     94 by <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code> or
     95 <code>{@link android.view.SurfaceHolder#lockCanvas() SurfaceHolder.lockCanvas()}</code> (see the following sections).</p>
     96 
     97 <p>The {@link android.graphics.Canvas} class has its own set of drawing methods that you can use,
     98 like <code>drawBitmap(...)</code>, <code>drawRect(...)</code>, <code>drawText(...)</code>, and many more.
     99 Other classes that you might use also have <code>draw()</code> methods. For example, you'll probably
    100 have some {@link android.graphics.drawable.Drawable} objects that you want to put on the Canvas. Drawable
    101 has its own <code>{@link android.graphics.drawable.Drawable#draw(Canvas) draw()}</code> method
    102 that takes your Canvas as an argument.</p>
    103 
    104 
    105 <h3 id="on-view">On a View</h3>
    106 
    107 <p>If your application does not require a significant amount of processing or
    108 frame-rate speed (perhaps for a chess game, a snake game,
    109 or another slowly-animated application), then you should consider creating a custom View component
    110 and drawing with a Canvas in <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code>.
    111 The most convenient aspect of doing so is that the Android framework will
    112 provide you with a pre-defined Canvas to which you will place your drawing calls.</p>
    113 
    114 <p>To start, extend the {@link android.view.View} class (or descendant thereof) and define
    115 the <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> callback method. This method will be called by the Android
    116 framework to request that your View draw itself. This is where you will perform all your calls
    117 to draw through the {@link android.graphics.Canvas}, which is passed to you through the <code>onDraw()</code> callback.</p>
    118 
    119 <p>The Android framework will only call <code>onDraw()</code> as necessary. Each time that
    120 your application is prepared to be drawn, you must request your View be invalidated by calling
    121 <code>{@link android.view.View#invalidate()}</code>. This indicates that you'd like your View to be drawn and
    122 Android will then call your <code>onDraw()</code> method (though is not guaranteed that the callback will
    123 be instantaneous). </p>
    124 
    125 <p>Inside your View component's <code>onDraw()</code>, use the Canvas given to you for all your drawing,
    126 using various <code>Canvas.draw...()</code> methods, or other class <code>draw()</code> methods that
    127 take your Canvas as an argument. Once your <code>onDraw()</code> is complete, the Android framework will
    128 use your Canvas to draw a Bitmap handled by the system.</p>
    129 
    130 <p class="note"><strong>Note: </strong> In order to request an invalidate from a thread other than your main
    131 Activity's thread, you must call <code>{@link android.view.View#postInvalidate()}</code>.</p>
    132 
    133 <p>For information about extending the {@link android.view.View} class, read
    134 <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>.</p>
    135 
    136 <p>For a sample application, see the Snake game, in the SDK samples folder:
    137 <code>&lt;your-sdk-directory>/samples/Snake/</code>.</p>
    138 
    139 <h3 id="on-surfaceview">On a SurfaceView</h3>
    140 
    141 <p>The {@link android.view.SurfaceView} is a special subclass of View that offers a dedicated
    142 drawing surface within the View hierarchy. The aim is to offer this drawing surface to
    143 an application's secondary thread, so that the application isn't required
    144 to wait until the system's View hierarchy is ready to draw. Instead, a secondary thread
    145 that has reference to a SurfaceView can draw to its own Canvas at its own pace.</p>
    146 
    147 <p>To begin, you need to create a new class that extends {@link android.view.SurfaceView}. The class should also
    148 implement {@link android.view.SurfaceHolder.Callback}. This subclass is an interface that will notify you
    149 with information about the underlying {@link android.view.Surface}, such as when it is created, changed, or destroyed.
    150 These events  are important so that you know when you can start drawing, whether you need
    151 to make adjustments based on new surface properties, and when to stop drawing and potentially
    152 kill some tasks. Inside your SurfaceView class is also a good place to define your secondary Thread class, which will
    153 perform all the drawing procedures to your Canvas.</p>
    154 
    155 <p>Instead of handling the Surface object directly, you should handle it via
    156 a {@link android.view.SurfaceHolder}. So, when your SurfaceView is initialized, get the SurfaceHolder by calling
    157 <code>{@link android.view.SurfaceView#getHolder()}</code>. You should then notify the SurfaceHolder that you'd
    158 like to receive SurfaceHolder callbacks (from {@link android.view.SurfaceHolder.Callback}) by calling
    159 {@link android.view.SurfaceHolder#addCallback(SurfaceHolder.Callback) addCallback()}
    160 (pass it <var>this</var>). Then override each of the
    161 {@link android.view.SurfaceHolder.Callback} methods inside your SurfaceView class.</p>
    162 
    163 <p>In order to draw to the Surface Canvas from within your second thread, you must pass the thread your SurfaceHandler
    164 and retrieve the Canvas with <code>{@link android.view.SurfaceHolder#lockCanvas() lockCanvas()}</code>.
    165 You can now take the Canvas given to you by the SurfaceHolder and do your necessary drawing upon it.
    166 Once you're done drawing with the Canvas, call
    167 <code>{@link android.view.SurfaceHolder#unlockCanvasAndPost(Canvas) unlockCanvasAndPost()}</code>, passing it
    168 your Canvas object. The Surface will now draw the Canvas as you left it. Perform this sequence of locking and
    169 unlocking the canvas each time you want to redraw.</p>
    170 
    171 <p class="note"><strong>Note:</strong> On each pass you retrieve the Canvas from the SurfaceHolder,
    172 the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the
    173 entire surface. For example, you can clear the previous state of the Canvas by filling in a color
    174 with <code>{@link android.graphics.Canvas#drawColor(int) drawColor()}</code> or setting a background image
    175 with <code>{@link android.graphics.Canvas#drawBitmap(Bitmap,Rect,RectF,Paint) drawBitmap()}</code>. Otherwise,
    176 you will see traces of the drawings you previously performed.</p>
    177 
    178 
    179 <p>For a sample application, see the Lunar Lander game, in the SDK samples folder:
    180 <code>&lt;your-sdk-directory>/samples/LunarLander/</code>. Or,
    181 browse the source in the <a href="{@docRoot}guide/samples/index.html">Sample Code</a> section.</p>
    182 
    183 <h2 id="drawables">Drawables</h2>
    184 <p>Android offers a custom 2D graphics library for drawing shapes and images.
    185   The {@link android.graphics.drawable} package is where you'll find the common classes used for
    186   drawing in two-dimensions.</p>
    187 
    188 <p>This document discusses the basics of using Drawable objects to draw graphics and how to use a
    189 couple subclasses of the Drawable class. For information on using Drawables to do frame-by-frame
    190 animation, see <a href="{@docRoot}guide/topics/graphics/drawable-animation.html">Drawable
    191 Animation</a>.</p>
    192 
    193 <p>A {@link android.graphics.drawable.Drawable} is a general abstraction for "something that can be
    194   drawn."  You'll discover that the Drawable class extends to define a variety of specific kinds of
    195 drawable graphics, including {@link android.graphics.drawable.BitmapDrawable}, {@link
    196   android.graphics.drawable.ShapeDrawable}, {@link android.graphics.drawable.PictureDrawable},
    197 {@link android.graphics.drawable.LayerDrawable}, and several more.  Of course, you can also extend
    198 these to define your own custom Drawable objects that behave in unique ways.</p>
    199 
    200 <p>There are three ways to define and instantiate a Drawable: using an image saved in your project
    201   resources; using an XML file that defines the Drawable properties; or using the normal class
    202 constructors. Below, we'll discuss each the first two techniques (using constructors is nothing new
    203 for an experienced developer).</p>
    204 
    205 
    206 <h3 id="drawables-from-images">Creating from resource images</h3>
    207 
    208 <p>A simple way to add graphics to your application is by referencing an image file from your
    209   project resources. Supported file types are PNG (preferred), JPG (acceptable) and GIF
    210 (discouraged). This technique would obviously be preferred for application icons, logos, or other
    211 graphics such as those used in a game.</p>
    212 
    213 <p>To use an image resource, just add your file to the <code>res/drawable/</code> directory of your
    214   project. From there, you can reference it from your code or your XML layout.
    215   Either way, it is referred using a resource ID, which is the file name without the file type
    216   extension (E.g., <code>my_image.png</code> is referenced as <var>my_image</var>).</p>
    217 
    218 <p class="note"><strong>Note:</strong> Image resources placed in <code>res/drawable/</code> may be
    219   automatically optimized with lossless image compression by the
    220   <code>aapt</code> tool during the build process. For example, a true-color PNG that does
    221   not require more than 256 colors may be converted to an 8-bit PNG with a color palette. This
    222   will result in an image of equal quality but which requires less memory. So be aware that the
    223   image binaries placed in this directory can change during the build. If you plan on reading
    224   an image as a bit stream in order to convert it to a bitmap, put your images in the
    225   <code>res/raw/</code> folder instead, where they will not be optimized.</p>
    226 
    227 <h4>Example code</h4>
    228 <p>The following code snippet demonstrates how to build an {@link android.widget.ImageView} that
    229   uses an image from drawable resources and add it to the layout.</p>
    230 <pre>
    231   LinearLayout mLinearLayout;
    232 
    233   protected void onCreate(Bundle savedInstanceState) {
    234   super.onCreate(savedInstanceState);
    235 
    236   // Create a LinearLayout in which to add the ImageView
    237   mLinearLayout = new LinearLayout(this);
    238 
    239   // Instantiate an ImageView and define its properties
    240   ImageView i = new ImageView(this);
    241   i.setImageResource(R.drawable.my_image);
    242   i.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable's dimensions
    243   i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT,
    244   LayoutParams.WRAP_CONTENT));
    245 
    246   // Add the ImageView to the layout and set the layout as the content view
    247   mLinearLayout.addView(i);
    248   setContentView(mLinearLayout);
    249   }
    250 </pre>
    251 <p>In other cases, you may want to handle your image resource as a
    252   {@link android.graphics.drawable.Drawable} object.
    253   To do so, create a Drawable from the resource like so:
    254   <pre>
    255     Resources res = mContext.getResources();
    256     Drawable myImage = res.getDrawable(R.drawable.my_image);
    257   </pre>
    258 
    259   <p class="warning"><strong>Note:</strong> Each unique resource in your project can maintain only
    260 one state, no matter how many different objects you may instantiate for it. For example, if you
    261     instantiate two Drawable objects from the same image resource, then change a property (such
    262 as the alpha) for one of the Drawables, then it will also affect the other. So when dealing with
    263 multiple instances of an image resource, instead of directly transforming the Drawable, you
    264 should perform a <a href="{@docRoot}guide/topics/graphics/view-animation.html#tween-animation">tween
    265 animation</a>.</p>
    266 
    267 
    268   <h4>Example XML</h4>
    269   <p>The XML snippet below shows how to add a resource Drawable to an
    270     {@link android.widget.ImageView} in the XML layout (with some red tint just for fun).
    271     <pre>
    272       &lt;ImageView
    273       android:layout_width="wrap_content"
    274       android:layout_height="wrap_content"
    275       android:tint="#55ff0000"
    276       android:src="@drawable/my_image"/>
    277   </pre>
    278   <p>For more information on using project resources, read about
    279     <a href="{@docRoot}guide/topics/resources/index.html">Resources and Assets</a>.</p>
    280 
    281 
    282   <h3 id="drawables-from-xml">Creating from resource XML</h3>
    283 
    284   <p>By now, you should be familiar with Android's principles of developing a
    285     <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>. Hence, you understand the
    286 power and flexibility inherent in defining objects in XML. This philosophy caries over from Views
    287 to Drawables.  If there is a Drawable object that you'd like to create, which is not initially
    288 dependent on variables defined by your application code or user interaction, then defining the
    289 Drawable in XML is a good option. Even if you expect your Drawable to change its properties
    290 during the user's experience with your application, you should consider defining the object in
    291 XML, as you can always modify properties once it is instantiated.</p>
    292 
    293   <p>Once you've defined your Drawable in XML, save the file in the <code>res/drawable/</code>
    294     directory of your project. Then, retrieve and instantiate the object by calling
    295     {@link android.content.res.Resources#getDrawable(int) Resources.getDrawable()}, passing it the
    296     resource ID of your XML file. (See the <a href="#drawable-xml-example">example
    297 below</a>.)</p>
    298 
    299   <p>Any Drawable subclass that supports the <code>inflate()</code> method can be defined in
    300     XML and instantiated by your application. Each Drawable that supports XML inflation utilizes
    301 specific XML attributes that help define the object
    302     properties (see the class reference to see what these are). See the class documentation for each
    303     Drawable subclass for information on how to define it in XML.
    304 
    305     <h4 id="drawable-xml-example">Example</h4>
    306     <p>Here's some XML that defines a TransitionDrawable:</p>
    307     <pre>
    308       &lt;transition xmlns:android="http://schemas.android.com/apk/res/android">
    309       &lt;item android:drawable="&#64;drawable/image_expand">
    310       &lt;item android:drawable="&#64;drawable/image_collapse">
    311       &lt;/transition>
    312     </pre>
    313 
    314     <p>With this XML saved in the file <code>res/drawable/expand_collapse.xml</code>,
    315       the following code will instantiate the TransitionDrawable and set it as the content of an
    316       ImageView:</p>
    317     <pre>
    318       Resources res = mContext.getResources();
    319       TransitionDrawable transition = (TransitionDrawable)
    320 res.getDrawable(R.drawable.expand_collapse);
    321       ImageView image = (ImageView) findViewById(R.id.toggle_image);
    322       image.setImageDrawable(transition);
    323     </pre>
    324     <p>Then this transition can be run forward (for 1 second) with:</p>
    325     <pre>transition.startTransition(1000);</pre>
    326 
    327     <p>Refer to the Drawable classes listed above for more information on the XML attributes
    328 supported by each.</p>
    329 
    330 
    331 
    332     <h2 id="shape-drawable">Shape Drawable</h2>
    333 
    334     <p>When you want to dynamically draw some two-dimensional graphics, a {@link
    335       android.graphics.drawable.ShapeDrawable}
    336       object will probably suit your needs. With a ShapeDrawable, you can programmatically draw
    337       primitive shapes and style them in any way imaginable.</p>
    338 
    339     <p>A ShapeDrawable is an extension of {@link android.graphics.drawable.Drawable}, so you can use
    340 one      where ever
    341       a Drawable is expected &mdash; perhaps for the background of a View, set with
    342       {@link android.view.View#setBackgroundDrawable(android.graphics.drawable.Drawable)
    343       setBackgroundDrawable()}.
    344       Of course, you can also draw your shape as its own custom {@link android.view.View},
    345       to be added to your layout however you please.
    346       Because the ShapeDrawable has its own <code>draw()</code> method, you can create a subclass of
    347 View      that
    348       draws the ShapeDrawable during the <code>View.onDraw()</code> method.
    349       Here's a basic extension of the View class that does just this, to draw a ShapeDrawable as a
    350       View:</p>
    351     <pre>
    352       public class CustomDrawableView extends View {
    353       private ShapeDrawable mDrawable;
    354 
    355       public CustomDrawableView(Context context) {
    356       super(context);
    357 
    358       int x = 10;
    359       int y = 10;
    360       int width = 300;
    361       int height = 50;
    362 
    363       mDrawable = new ShapeDrawable(new OvalShape());
    364       mDrawable.getPaint().setColor(0xff74AC23);
    365       mDrawable.setBounds(x, y, x + width, y + height);
    366       }
    367 
    368       protected void onDraw(Canvas canvas) {
    369       mDrawable.draw(canvas);
    370       }
    371       }
    372     </pre>
    373 
    374     <p>In the constructor, a ShapeDrawable is defines as an {@link
    375       android.graphics.drawable.shapes.OvalShape}.
    376       It's then given a color and the bounds of the shape are set. If you do not set the bounds,
    377 then the
    378       shape will not be drawn, whereas if you don't set the color, it will default to black.</p>
    379     <p>With the custom View defined, it can be drawn any way you like. With the sample above, we can
    380       draw the shape programmatically in an Activity:</p>
    381     <pre>
    382       CustomDrawableView mCustomDrawableView;
    383 
    384       protected void onCreate(Bundle savedInstanceState) {
    385       super.onCreate(savedInstanceState);
    386       mCustomDrawableView = new CustomDrawableView(this);
    387 
    388       setContentView(mCustomDrawableView);
    389       }
    390     </pre>
    391 
    392     <p>If you'd like to draw this custom drawable from the XML layout instead of from the Activity,
    393       then the CustomDrawable class must override the {@link
    394       android.view.View#View(android.content.Context, android.util.AttributeSet) View(Context,
    395       AttributeSet)} constructor, which is called when
    396       instantiating a View via inflation from XML. Then add a CustomDrawable element to the XML,
    397       like so:</p>
    398     <pre>
    399       &lt;com.example.shapedrawable.CustomDrawableView
    400       android:layout_width="fill_parent"
    401       android:layout_height="wrap_content"
    402       />
    403   </pre>
    404 
    405   <p>The ShapeDrawable class (like many other Drawable types in the {@link
    406 android.graphics.drawable}    package)
    407     allows you to define various properties of the drawable with public methods.
    408     Some properties you might want to adjust include
    409     alpha transparency, color filter, dither, opacity and color.</p>
    410 
    411   <p>You can also define primitive drawable shapes using XML. For more information, see the
    412     section about Shape Drawables in the <a
    413 
    414 href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a>
    415     document.</p>
    416 
    417   <!-- TODO
    418        <h2 id="state-list">StateListDrawable</h2>
    419 
    420        <p>A StateListDrawable is an extension of the DrawableContainer class, making it  little
    421 different.
    422          The primary distinction is that the
    423          StateListDrawable manages a collection of images for the Drawable, instead of just one.
    424          This means that it can switch the image when you want, without switching objects. However,
    425 the
    426          intention of the StateListDrawable is to automatically change the image used based on the
    427 state
    428          of the object it's attached to.
    429          -->
    430 
    431          <h2 id="nine-patch">Nine-patch</h2>
    432 
    433          <p>A {@link android.graphics.drawable.NinePatchDrawable} graphic is a stretchable bitmap
    434 image,           which Android
    435            will automatically resize to accommodate the contents of the View in which you have
    436 placed it as the           background.
    437            An example use of a NinePatch is the backgrounds used by standard Android buttons &mdash;
    438            buttons must stretch to accommodate strings of various lengths. A NinePatch drawable is a
    439 standard           PNG
    440            image that includes an extra 1-pixel-wide border. It must be saved with the extension
    441            <code>.9.png</code>,
    442            and saved into the <code>res/drawable/</code> directory of your project.
    443          </p>
    444          <p>
    445            The border is used to define the stretchable and static areas of
    446            the image. You indicate a stretchable section by drawing one (or more) 1-pixel-wide
    447            black line(s) in the left and top part of the border (the other border pixels should
    448            be fully transparent or white). You can have as many stretchable sections as you want:
    449            their relative size stays the same, so the largest sections always remain the largest.
    450          </p>
    451          <p>
    452            You can also define an optional drawable section of the image (effectively,
    453            the padding lines) by drawing a line on the right and bottom lines.
    454            If a View object sets the NinePatch as its background and then specifies the
    455            View's text, it will stretch itself so that all the text fits inside only
    456            the area designated by the right and bottom lines (if included). If the
    457            padding lines are not included, Android uses the left and top lines to
    458            define this drawable area.
    459          </p>
    460          <p>To clarify the difference between the different lines, the left and top lines define
    461            which pixels of the image are allowed to be replicated in order to stretch the image.
    462            The bottom and right lines define the relative area within the image that the contents
    463            of the View are allowed to lie within.</p>
    464          <p>
    465            Here is a sample NinePatch file used to define a button:
    466          </p>
    467          <img src="{@docRoot}images/ninepatch_raw.png" alt="" />
    468 
    469          <p>This NinePatch defines one stretchable area with the left and top lines
    470            and the drawable area with the bottom and right lines. In the top image, the dotted grey
    471            lines identify the regions of the image that will be replicated in order to stretch the
    472 image. The           pink
    473            rectangle in the bottom image identifies the region in which the contents of the View are
    474 allowed.
    475            If the contents don't fit in this region, then the image will be stretched so that they
    476 do.
    477 </p>
    478 
    479 <p>The <a href="{@docRoot}tools/help/draw9patch.html">Draw 9-patch</a> tool offers
    480    an extremely handy way to create your NinePatch images, using a WYSIWYG graphics editor. It
    481 even raises warnings if the region you've defined for the stretchable area is at risk of
    482 producing drawing artifacts as a result of the pixel replication.
    483 </p>
    484 
    485 <h3>Example XML</h3>
    486 
    487 <p>Here's some sample layout XML that demonstrates how to add a NinePatch image to a
    488 couple of buttons. (The NinePatch image is saved as
    489 <code>res/drawable/my_button_background.9.png</code>
    490 <pre>
    491 &lt;Button id="@+id/tiny"
    492         android:layout_width="wrap_content"
    493         android:layout_height="wrap_content"
    494         android:layout_alignParentTop="true"
    495         android:layout_centerInParent="true"
    496         android:text="Tiny"
    497         android:textSize="8sp"
    498         android:background="@drawable/my_button_background"/&gt;
    499 
    500 &lt;Button id="@+id/big"
    501         android:layout_width="wrap_content"
    502         android:layout_height="wrap_content"
    503         android:layout_alignParentBottom="true"
    504         android:layout_centerInParent="true"
    505         android:text="Biiiiiiig text!"
    506         android:textSize="30sp"
    507         android:background="@drawable/my_button_background"/&gt;
    508 </pre>
    509 <p>Note that the width and height are set to "wrap_content" to make the button fit neatly around the
    510 text.
    511 </p>
    512 
    513 <p>Below are the two buttons rendered from the XML and NinePatch image shown above.
    514 Notice how the width and height of the button varies with the text, and the background image
    515 stretches to accommodate it.
    516 </p>
    517 
    518 <img src="{@docRoot}images/ninepatch_examples.png" alt=""/>