Merge "SDK docs: Hierarchy Viewer V2" into honeycomb
diff --git a/Android.mk b/Android.mk
index 18e0963..27c4bec8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -427,10 +427,14 @@
resources/samples/Spinner "Spinner" \
-samplecode $(sample_dir)/SpinnerTest \
resources/samples/SpinnerTest "SpinnerTest" \
+ -samplecode $(sample_dir)/StackWidget \
+ resources/samples/StackWidget "StackView Widget" \
-samplecode $(sample_dir)/TicTacToeLib \
resources/samples/TicTacToeLib "TicTacToeLib" \
-samplecode $(sample_dir)/TicTacToeMain \
resources/samples/TicTacToeMain "TicTacToeMain" \
+ -samplecode $(sample_dir)/WeatherListWidget \
+ resources/samples/WeatherListWidget "Weather List Widget" \
-samplecode $(sample_dir)/Wiktionary \
resources/samples/Wiktionary "Wiktionary" \
-samplecode $(sample_dir)/WiktionarySimple \
diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd
index 6ca8acc..f826f43 100644
--- a/docs/html/guide/appendix/market-filters.jd
+++ b/docs/html/guide/appendix/market-filters.jd
@@ -5,23 +5,25 @@
<div id="qv">
<h2>Quickview</h2>
-<ul> <li>Android Market applies filters to that let you control whether your app is shown to a
-user who is browing or searching for apps.</li>
-<li>Filtering is determined by elements in an app's manifest file,
-aspects of the device being used, and other factors.</li> </ul>
+<ul>
+<li>Android Market applies filters that control which Android-powered devices can access your
+application on Market.</li>
+<li>Filtering is determined by comparing device configurations that you declare in you app's
+manifest file to the configurations defined by the device, as well as other factors.</li> </ul>
<h2>In this document</h2>
<ol> <li><a href="#how-filters-work">How Filters Work in Android Market</a></li>
<li><a href="#manifest-filters">Filtering based on Manifest File Elements</a></li>
<li><a href="#other-filters">Other Filters</a></li>
+<li><a href="#advanced-filters">Advanced Manifest Filters</a></li>
</ol>
<h2>See also</h2>
<ol>
<li><a
-href="{@docRoot}guide/practices/compatibility.html">Compatibility</a></li>
-<li style="margin-top:2px;"><code><a
+href="{@docRoot}guide/practices/compatibility.html">Android Compatibility</a></li>
+<li><code><a
href="{@docRoot}guide/topics/manifest/supports-screens-element.html"><supports-screens></a></code></li>
<li><code><a
href="{@docRoot}guide/topics/manifest/uses-configuration-element.html"><uses-configuration></a></code></li>
@@ -42,36 +44,40 @@
href="http://market.android.com/publish">Go to Android Market »</a> </div>
</div>
-</div> </div>
+</div>
+</div>
-<p>When a user searches or browses in Android Market, the results are filtered, and
-some applications might not be visible. For example, if an application requires a
+
+<p>When a user searches or browses in Android Market, the results are filtered based on which
+applications are compatible with the user's device. For example, if an application requires a
trackball (as specified in the manifest file), then Android Market will not show
-the app on any device that does not have a trackball.</p> <p>The manifest file and
-the device's hardware and features are only part of how applications are filtered
-— filtering also depends on the country and carrier, the presence or absence
-of a SIM card, and other factors. </p>
+the app on any device that does not have a trackball.</p>
+
+<p>The manifest file and the device's hardware and features are only part of how applications are
+filtered—filtering might also depend on the country and carrier, the presence or absence of a
+SIM card, and other factors. </p>
<p>Changes to the Android Market filters are independent of changes
to the Android platform itself. This document will be updated periodically to reflect
-any changes that occur. </p>
+any changes that affect the way Android Market filters applications.</p>
+
<h2 id="how-filters-work">How Filters Work in Android Market</h2>
<p>Android Market uses the filter restrictions described below to determine
whether to show your application to a user who is browsing or searching for
-applications on a given device. When determining whether to display your app,
+applications on an Android-powered device. When determining whether to display your app,
Market checks the device's hardware and software capabilities, as well as it's
carrier, location, and other characteristics. It then compares those against the
restrictions and dependencies expressed by the application itself, in its
-manifest, <code>.apk</code>, and publishing details. If the application is
+manifest file and publishing details. If the application is
compatible with the device according to the filter rules, Market displays the
application to the user. Otherwise, Market hides your application from search
results and category browsing. </p>
-<p> You can use the filters described below to control whether Market shows or
-hides your application to users. You can request any combination of the
-available filters for your app — for example, you could set a
+<p>You can use the filters described below to control whether Market shows or
+hides your application to users. You can use any combination of the
+available filters for your app—for example, you can set a
<code>minSdkVersion</code> requirement of <code>"4"</code> and set
<code>smallScreens="false"</code> in the app, then when uploading the app to
Market you could target European countries (carriers) only. Android Market's
@@ -92,16 +98,18 @@
available. </li>
</ul>
+
+
<h2 id="manifest-filters">Filtering based on Manifest Elements</h2>
<p>Most Market filters are triggered by elements within an application's
manifest file, <a
href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a>,
-although not everything in the manifest file can trigger filtering. The
-table below lists the manifest elements that you can use to trigger Android
-Market filtering, and explains how the filtering works.</p>
+although not everything in the manifest file can trigger filtering.
+Table 1 lists the manifest elements that you should use to trigger Android
+Market filtering, and explains how the filtering for each element works.</p>
-<p class="table-caption"><strong>Table 1.</strong> Manifest elements that
+<p id="table1" class="table-caption"><strong>Table 1.</strong> Manifest elements that
trigger filtering on Market.</p>
<table>
<tr>
@@ -313,10 +321,13 @@
</tr>
</table>
+
<h2 id="other-filters">Other Filters</h2>
+
<p>Android Market uses other application characteristics to determine whether to show or hide an application for a particular user on a given device, as described in the table below. </p>
-<p class="table-caption"><strong>Table 2.</strong> Application and publishing characteristics that affect filtering on Market.</p>
+<p id="table2" class="table-caption"><strong>Table 2.</strong> Application and publishing
+characteristics that affect filtering on Market.</p>
<table> <tr>
<th>Filter Name</th> <th>How It Works</th> </tr>
@@ -351,3 +362,38 @@
developer devices or unreleased devices.</p></td> </tr> </table>
+
+
+<h2 id="advanced-filters">Advanced Manifest Filters</h2>
+
+<p>In addition to the manifest elements in <a href="#table1">table 1</a>, Android Market can also
+filter applications based on the advanced manifest elements in table 3.</p>
+
+<p>These manifest elements and the filtering they trigger are for exceptional use-cases
+only. They are designed for some types of high-performance games and similar applications that
+require strict controls on application distribution. <strong>Most applications should never use
+these filters</strong>.</p>
+
+<p id="table3" class="table-caption"><strong>Table 3.</strong> Advanced manifest elements for
+Android Market filtering.</p>
+<table>
+ <tr><th>Manifest Element</th><th>Summary</th></tr>
+ <tr>
+ <td><nobr><a href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">{@code
+<compatible-screens>}</a></nobr></td>
+ <td>
+ <p>Android Market filters the application if the device screen size and density does not match
+any of the screen configurations (declared by a {@code <screen>} element) in the {@code
+<compatible-screens>} element.</p>
+ <p class="caution"><strong>Caution:</strong> Normally, <strong>you should not use
+this manifest element</strong>. Using this element can dramatically
+reduce the potential user base for your application, by excluding all combinations of screen size
+and density that you have not listed. You should instead use the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+<supports-screens>}</a> manifest element (described above in <a href="#table1">table
+1</a>) to enable screen compatibility mode for screen configurations you have not accounted for
+with alternative resources.</p>
+ </td>
+ </tr>
+</table>
+
diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd
index 8709994..bac6bf4 100644
--- a/docs/html/guide/appendix/media-formats.jd
+++ b/docs/html/guide/appendix/media-formats.jd
@@ -1,29 +1,72 @@
page.title=Android Supported Media Formats
@jd:body
-<p>The <a href="#core">Core Media Formats</a> table below describes the media format support built into the Android platform. Note that any given mobile device may provide support for additional formats or file types not listed in the table. </p>
+<div id="qv-wrapper">
+<div id="qv">
-<p>As an application developer, you are free to make use of any media codec that is available on any Android-powered device, including those provided by the Android platform and those that are device-specific.</p>
+<h2>In this document</h2>
+
+<ol>
+<li><a href="#network">Network Protocols</a></li>
+<li><a href="#core">Core Media Formats</a></li>
+<li><a href="#recommendations">Video Encoding Recommendations</a></li>
+</ol>
+
+<h2>See also</h2>
+<ol>
+<li><a href="{@docRoot}guide/topics/media/index.html">Audio and Video</a></li>
+</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.media.MediaPlayer MediaPlayer}</li>
+<li>{@link android.media.MediaRecorder MediaRecorder}</li>
+</ol>
+
+</div>
+</div>
+
+<p>This document describes the media codec, container, and network protocol support provided by the Android platform.</p>
+
+<p>As an application developer, you are free to make use of any media codec that is available on any Android-powered device, including those provided by the Android platform and those that are device-specific. <strong>However, it is a best practice to use media encoding profiles that are device-agnostic</strong>.</p>
+
+
+<h2 id="network">Network Protocols</h2>
+
+<p>The following network protocols are supported for audio and video playback:</p>
+
+<ul>
+ <li>RTSP (RTP, SDP)</li>
+ <li>HTTP progressive streaming</li>
+ <li>HTTP live streaming <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-05">draft protocol</a> (Android 3.0 and above)</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> HTTPS is not supported at this time.</p>
+
<h2 id="core">Core Media Formats</h2>
+<p>The table below describes the media format support built into the Android platform. Note that any given mobile device may provide support for additional formats or file types not listed in the table.</p>
+
+<p class="note"><strong>Note:</strong> Media codecs that are not guaranteed to be available on all Android platform versions are accordingly noted in parentheses—for example "(Android 3.0+)".</p>
+
<table>
<tbody>
<tr>
<th>Type</th>
-<th>Format</th>
+<th>Format / Codec</th>
<th>Encoder</th>
<th>Decoder</th>
<th>Details</th>
-<th>File Type(s) Supported</th>
+<th>Supported File Type(s) / Container Formats</th>
</tr>
<tr>
<td rowspan="9">Audio</td>
<td>AAC LC/LTP</td>
-<td style="text-align: center;">X</td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
+<td style="text-align: center;"><big>•</big></td>
<td rowspan="3">Mono/Stereo content in any combination of standard bit rates up to 160 kbps and sampling rates from 8 to 48kHz</td>
<td rowspan="3">3GPP (.3gp) and MPEG-4 (.mp4, .m4a). No support for raw AAC (.aac)</td>
</tr>
@@ -31,19 +74,19 @@
<tr>
<td>HE-AACv1 (AAC+)</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
</tr>
<tr>
<td>HE-AACv2 (enhanced AAC+)</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
</tr>
<tr>
<td>AMR-NB</td>
-<td style="text-align: center;">X</td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
+<td style="text-align: center;"><big>•</big></td>
<td>4.75 to 12.2 kbps sampled @ 8kHz</td>
<td>3GPP (.3gp)
</td>
@@ -51,8 +94,8 @@
<tr>
<td>AMR-WB</td>
-<td style="text-align: center;">X</td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
+<td style="text-align: center;"><big>•</big></td>
<td>9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16kHz</td>
<td>3GPP (.3gp)</td>
</tr>
@@ -60,7 +103,7 @@
<tr>
<td>MP3</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
<td>Mono/Stereo 8-320Kbps constant (CBR) or variable bit-rate (VBR)
</td>
<td>MP3 (.mp3)</td>
@@ -69,7 +112,7 @@
<tr>
<td>MIDI</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
<td>MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for ringtone formats RTTTL/RTX, OTA, and iMelody </td>
<td>Type 0 and 1 (.mid, .xmf, .mxmf). Also RTTTL/RTX (.rtttl, .rtx), OTA (.ota), and iMelody (.imy)</td>
</tr>
@@ -77,7 +120,7 @@
<tr>
<td>Ogg Vorbis</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
<td> </td>
<td>Ogg (.ogg)</td>
</tr>
@@ -85,7 +128,7 @@
<tr>
<td>PCM/WAVE</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
<td>8- and 16-bit linear PCM (rates up to limit of hardware)</td>
<td>WAVE (.wav)</td>
</tr>
@@ -93,8 +136,8 @@
<tr>
<td rowspan="4">Image</td>
<td>JPEG</td>
-<td style="text-align: center;">X</td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
+<td style="text-align: center;"><big>•</big></td>
<td>Base+progressive</td>
<td>JPEG (.jpg)</td>
</tr>
@@ -102,15 +145,15 @@
<tr>
<td>GIF</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
<td> </td>
<td>GIF (.gif)</td>
</tr>
<tr>
<td>PNG</td>
-<td style="text-align: center;">X</td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
+<td style="text-align: center;"><big>•</big></td>
<td> </td>
<td>PNG (.png)</td>
</tr>
@@ -118,33 +161,33 @@
<tr>
<td>BMP</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
<td> </td>
<td>BMP (.bmp)</td>
</tr>
-
+
<tr>
<td rowspan="3">Video</td>
<td>H.263</td>
-<td style="text-align: center;">X</td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
+<td style="text-align: center;"><big>•</big></td>
<td> </td>
<td>3GPP (.3gp) and MPEG-4 (.mp4)</td>
</tr>
<tr>
<td>H.264 AVC</td>
-<td style="text-align: center;"></td>
-<td style="text-align: center;">X</td>
-<td> </td>
+<td style="text-align: center;" nowrap><big>•</big><br><small>(Android 3.0+)</small></td>
+<td style="text-align: center;"><big>•</big></td>
+<td>Baseline Profile (BP)</td>
<td>3GPP (.3gp) and MPEG-4 (.mp4)</td>
</tr>
<tr>
<td>MPEG-4 SP</td>
<td> </td>
-<td style="text-align: center;">X</td>
+<td style="text-align: center;"><big>•</big></td>
<td> </td>
<td>3GPP (.3gp)</td>
</tr>
@@ -152,7 +195,83 @@
</tbody></table>
+<h2 id="recommendations">Video Encoding Recommendations</h2>
+<p>Below are examples of video encoding profiles and parameters that the Android media framework supports for playback.</p>
+<ul>
+ <li><strong>Lower quality video</strong><br>
+ <table style="margin-top: 4px">
+ <tbody>
+ <tr>
+ <th>Video codec</th>
+ <td>H.264 Baseline Profile</th>
+ </tr>
+ <tr>
+ <th>Video resolution</th>
+ <td>176 x 144 px</th>
+ </tr>
+ <tr>
+ <th>Video frame rate</th>
+ <td>12 fps</th>
+ </tr>
+ <tr>
+ <th>Video bitrate</th>
+ <td>56 Kbps</th>
+ </tr>
+ <tr>
+ <th>Audio codec</th>
+ <td>AAC-LC</th>
+ </tr>
+ <tr>
+ <th>Audio channels</th>
+ <td>1 (mono)</th>
+ </tr>
+ <tr>
+ <th>Audio bitrate</th>
+ <td>24 Kbps</th>
+ </tr>
+ </tbody>
+ </table>
+ </li>
+ <li><strong>Higher quality video</strong><br>
+
+ <table style="margin-top: 4px">
+ <tbody>
+ <tr>
+ <th>Video codec</th>
+ <td>H.264 Baseline Profile</th>
+ </tr>
+ <tr>
+ <th>Video resolution</th>
+ <td>480 x 360 px</th>
+ </tr>
+ <tr>
+ <th>Video frame rate</th>
+ <td>30 fps</th>
+ </tr>
+ <tr>
+ <th>Video bitrate</th>
+ <td>500 Kbps</th>
+ </tr>
+ <tr>
+ <th>Audio codec</th>
+ <td>AAC-LC</th>
+ </tr>
+ <tr>
+ <th>Audio channels</th>
+ <td>2 (stereo)</th>
+ </tr>
+ <tr>
+ <th>Audio bitrate</th>
+ <td>128 Kbps</th>
+ </tr>
+ </tbody>
+ </table>
+
+ </li>
+</ul>
+
+<p>In addition to the encoding parameters above, a device's available video recording profiles can be used as a proxy for media playback capabilities. These profiles can be inspected using the {@link android.media.CamcorderProfile CamcorderProfile} class, which is available since API level 8.</p>
diff --git a/docs/html/guide/developing/testing/index.jd b/docs/html/guide/developing/testing/index.jd
index 8ffaf58..8a08959 100644
--- a/docs/html/guide/developing/testing/index.jd
+++ b/docs/html/guide/developing/testing/index.jd
@@ -18,14 +18,14 @@
which guides you through a more complex testing scenario.
</p>
<dl>
- <dt><a href="testing_eclipse.html">Testing in Eclipse, with ADT</a></dt>
+ <dt><a href="testing_eclipse.html">Testing from Eclipse, with ADT</a></dt>
<dd>
The ADT plugin lets you quickly set up and manage test projects directly in
the Eclipse UI. Once you have written your tests, you can build and run them and
then see the results in the Eclipse JUnit view. You can also use the SDK command-line
tools to execute your tests if needed.
</dd>
- <dt><a href="testing_otheride.html">Testing in Other IDEs</a></dt>
+ <dt><a href="testing_otheride.html">Testing from Other IDEs</a></dt>
<dd>
The SDK command-line tools provide the same capabilities as the ADT plugin. You can
use them to set up and manage test projects, build your test application,
diff --git a/docs/html/guide/developing/tools/monkeyrunner_concepts.jd b/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
index d648b93..658ff75 100644
--- a/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
+++ b/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
@@ -110,8 +110,17 @@
# to see if the installation worked.
device.installPackage('myproject/bin/MyApplication.apk')
-# Runs an activity in the application
-device.startActivity(component='com.example.android.myapplication.MainActivity')
+# sets a variable with the package's internal name
+package = 'com.example.android.myapplication'
+
+# sets a variable with the name of an Activity in the package
+activity = 'com.example.android.myapplication.MainActivity'
+
+# sets the name of the component to start
+runComponent = package + '/' + activity
+
+# Runs the component
+device.startActivity(component=runComponent)
# Presses the Menu button
device.press('KEYCODE_MENU','DOWN_AND_UP')
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index a375b11..ce516ce 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -65,6 +65,9 @@
<li><a href="<?cs var:toroot ?>guide/topics/fundamentals/fragments.html">
<span class="en">Fragments</span>
</a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/providers/loaders.html">
+ <span class="en">Loaders</span>
+ </a><span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>guide/topics/fundamentals/tasks-and-back-stack.html">
<span class="en">Tasks and Back Stack</span>
</a></li>
@@ -95,8 +98,9 @@
<ul>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/ui/index.html">
- <span class="en">User Interface</span>
- </a></div>
+ <span class="en">User Interface</span>
+ </a>
+ <span class="new">more!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/ui/declaring-layout.html">
<span class="en">Declaring Layout</span>
@@ -125,7 +129,12 @@
<span class="en">Creating Status Bar Notifications</span>
</a></li>
</ul>
- </li><!-- end of notifying the user -->
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>guide/topics/ui/drag-drop.html">
+ Dragging and Dropping
+ </a><span class="new">new!</span>
+ </li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/themes.html">
<span class="en">Applying Styles and Themes</span>
</a></li>
@@ -202,6 +211,7 @@
<li><a href="<?cs var:toroot ?>guide/topics/manifest/activity-alias-element.html"><activity-alias></a></li>
<li><a href="<?cs var:toroot ?>guide/topics/manifest/application-element.html"><application></a></li>
<li><a href="<?cs var:toroot ?>guide/topics/manifest/category-element.html"><category></a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/manifest/compatible-screens-element.html"><compatible-screens></a></li>
<li><a href="<?cs var:toroot ?>guide/topics/manifest/data-element.html"><data></a></li>
<li><a href="<?cs var:toroot ?>guide/topics/manifest/grant-uri-permission-element.html"><grant-uri-permission></a></li>
<li><a href="<?cs var:toroot ?>guide/topics/manifest/instrumentation-element.html"><instrumentation></a></li>
@@ -228,8 +238,9 @@
<ul>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/graphics/index.html">
- <span class="en">Graphics</span>
- </a></div>
+ <span class="en">Graphics</span>
+ </a>
+ <span class="new">more!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/graphics/2d-graphics.html">
<span class="en">2D Graphics</span>
@@ -237,14 +248,26 @@
<li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html">
<span class="en">3D with OpenGL</span>
</a></li>
- <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
- <span class="en">Animation</span>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/renderscript.html">
+ <span class="en">3D with Renderscript</span>
</a><span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
+ <span class="en">Property Animation</span>
+ </a><span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/view-animation.html">
+ <span class="en">View Animation</span>
+ </a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/media/index.html">
<span class="en">Audio and Video</span>
</a></li>
+ <li>
+ <a href="<?cs var:toroot ?>guide/topics/clipboard/copy-paste.html">
+ <span class="en">Copy and Paste</span>
+ </a>
+ <span class="new">new!</span>
+ </li>
<!--<li class="toggle-list">
<div><a style="color:gray;">Sensors</a></div>
<ul>
@@ -393,24 +416,24 @@
<li class="toggle-list">
<div>
<a href="<?cs var:toroot ?>guide/developing/devices/index.html">
- <span class="en">Managing Virtual Devices</span>
- </a>
+ <span class="en">Creating and Managing Virtual Devices</span>
+ </a>
</div>
<ul>
<li>
<a href="<?cs var:toroot ?>guide/developing/devices/managing-avds.html">
<span class="en">With AVD Manager</span>
- </a>
+ </a>
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/devices/managing-avds-cmdline.html">
- <span class="en">From the Command Line</span>
- </a>
+ <span class="en">On the Command Line</span>
+ </a>
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/devices/emulator.html">
- <span class="en">Using the Android Emulator</span>
- </a>
+ <span class="en">Using the Android Emulator</span>
+ </a>
</li>
</ul>
</li>
@@ -419,7 +442,7 @@
<span class="en">Using Hardware Devices</span>
</a>
</li>
-
+
<li class="toggle-list">
<div>
<a href="<?cs var:toroot ?>guide/developing/projects/index.html">
@@ -434,7 +457,7 @@
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/projects/projects-cmdline.html">
- <span class="en">From the Command Line</span>
+ <span class="en">On the Command Line</span>
</a>
</li>
</ul>
@@ -464,12 +487,12 @@
<ul>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-projects.html">
- <span class="en">From Eclipse with ADT</span>
+ <span class="en">In Eclipse with ADT</span>
</a>
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-projects-cmdline.html">
- <span class="en">From Other IDEs</span>
+ <span class="en">In Other IDEs</span>
</a>
</li>
<li>
@@ -479,23 +502,23 @@
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-log.html">
- <span class="en">Reading and Writing Logs</span>
+ <span class="en">Reading and Writing Log Messages</span>
</a>
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-ui.html">
- <span class="en">Debugging and Profiling UIs</span>
- </a>
+ <span class="en">Debugging and Profiling UIs</span>
+ </a>
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-tracing.html">
- <span class="en">Profiling with Traceview and dmtracedump</span>
- </a>
+ <span class="en">Profiling with Traceview and dmtracedump</span>
+ </a>
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-devtools.html">
- <span class="en">Using the Dev Tools App</span>
- </a>
+ <span class="en">Using the Dev Tools App</span>
+ </a>
</li>
</ul>
</li>
@@ -725,7 +748,7 @@
</a></li>
<li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">
<span class="en">Supported Media Formats</span>
- </a></li>
+ </a> <span class="new">updated</span></li>
<li><a href="<?cs var:toroot ?>guide/appendix/g-app-intents.html">
<span class="en">Intents List: Google Apps</span>
</a></li>
diff --git a/docs/html/guide/samples/index.jd b/docs/html/guide/samples/index.jd
index bd9ea52..4b9334f 100644
--- a/docs/html/guide/samples/index.jd
+++ b/docs/html/guide/samples/index.jd
@@ -4,11 +4,11 @@
<script type="text/javascript">
- window.location = toRoot + "resources/samples/index.html";
+ window.location = toRoot + "resources/browser.html?tag=sample";
</script>
<p><strong>This document has moved. Please go to <a
-href="http://developer.android.com/resources/samples/index.html">List of Sample
+href="http://developer.android.com/resources/browser.html?tag=sample">List of Sample
Apps</a>.</strong></p>
diff --git a/docs/html/guide/topics/clipboard/copy-paste.jd b/docs/html/guide/topics/clipboard/copy-paste.jd
new file mode 100644
index 0000000..6c86f47
--- /dev/null
+++ b/docs/html/guide/topics/clipboard/copy-paste.jd
@@ -0,0 +1,1094 @@
+page.title=Copy and Paste
+@jd:body
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>Quickview</h2>
+ <ul>
+ <li>
+ A clipboard-based framework for copying and pasting data.
+ </li>
+ <li>
+ Supports both simple and complex data, including text strings, complex data
+ structures, text and binary stream data, and application assets.
+ </li>
+ <li>
+ Copies and pastes simple text directly to and from the clipboard.
+ </li>
+ <li>
+ Copies and pastes complex data using a content provider.
+ </li>
+ <li>
+ Requires API 11.
+ </li>
+ </ul>
+ <h2>In this document</h2>
+ <ol>
+ <li>
+ <a href="#Clipboard">The Clipboard Framework</a>
+ </li>
+ <li>
+ <a href="#ClipboardClasses">Clipboard Classes</a>
+ <ol>
+ <li>
+ <a href="#ClipboardManager">ClipboardManager</a>
+ </li>
+ <li>
+ <a href="#ClipClasses">
+ ClipData, ClipDescription, and ClipData.Item
+ </a>
+ </li>
+ <li>
+ <a href="#ClipDataMethods">ClipData convenience methods</a>
+ </li>
+ <li>
+ <a href="#CoerceToText">Coercing the clipboard data to text</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#Copying">Copying to the Clipboard</a>
+ </li>
+ <li>
+ <a href="#Pasting">Pasting from the Clipboard</a>
+ <ol>
+ <li>
+ <a href="#PastePlainText">Pasting plain text</a>
+ </li>
+ <li>
+ <a href="#PasteContentUri">Pasting data from a content URI</a>
+ </li>
+ <li>
+ <a href="#PasteIntent">Pasting an Intent</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#Provider">Using Content Providers to Copy Complex Data</a>
+ <ol>
+ <li>
+ <a href="#Encoding">Encoding an identifier on the URI</a>
+ </li>
+ <li>
+ <a href="#Records">Copying data structures</a>
+ </li>
+ <li>
+ <a href="#Streams">Copying data streams</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#DataDesign">Designing Effective Copy/Paste Functionality</a>
+ </li>
+ </ol>
+ <h2>Key classes</h2>
+ <ol>
+ <li>
+ {@link android.content.ClipboardManager ClipboardManager}
+ </li>
+ <li>
+ {@link android.content.ClipData ClipData}
+ </li>
+ <li>
+ {@link android.content.ClipData.Item ClipData.Item}
+ </li>
+ <li>
+ {@link android.content.ClipDescription ClipDescription}
+ </li>
+ <li>
+ {@link android.net.Uri Uri}
+ </li>
+ <li>
+ {@link android.content.ContentProvider}
+ </li>
+ <li>
+ {@link android.content.Intent Intent}
+ </li>
+ </ol>
+ <h2>Related Samples</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/NotePad/index.html">
+ Note Pad sample application</a>
+ </li>
+ </ol>
+ <h2>See also</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+ </li>
+ </ol>
+ </div>
+</div>
+<p>
+ Android provides a powerful clipboard-based framework for copying and pasting. It
+ supports both simple and complex data types, including text strings, complex data
+ structures, text and binary stream data, and even application assets. Simple text data is stored
+ directly in the clipboard, while complex data is stored as a reference that the pasting
+ application resolves with a content provider. Copying and pasting works both within an
+ application and between applications that implement the framework.
+</p>
+
+<p>
+ Since a part of the framework uses content providers, this topic assumes some
+ familiarity with the Android Content Provider API, which is described in the topic
+ <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
+</p>
+<h2 id="Clipboard">The Clipboard Framework</h2>
+<p>
+ When you use the clipboard framework, you put data into a clip object, and then
+ put the clip object on the system-wide clipboard. The clip object can take one of three forms:
+</p>
+ <dl>
+ <dt>Text</dt>
+ <dd>
+ A text string. You put the string directly into the clip object, which you then put onto
+ the clipboard. To paste the string, you get the clip object from the clipboard and copy
+ the string to into your application's storage.
+ </dd>
+ <dt>URI</dt>
+ <dd>
+ A {@link android.net.Uri} object representing any form of URI. This is primarily for
+ copying complex data from a content provider. To copy data, you put a
+ {@link android.net.Uri} object into a clip object and put the clip object onto
+ the clipboard. To paste the data, you get the clip object, get the
+ {@link android.net.Uri} object, resolve it to a data source such as a content provider,
+ and copy the data from the source into your application's storage.
+ </dd>
+ <dt>Intent</dt>
+ <dd>
+ An {@link android.content.Intent}. This supports copying application shortcuts. To copy
+ data, you create an Intent, put it into a clip object, and put the clip object onto the
+ clipboard. To paste the data, you get the clip object and then copy the Intent object
+ into your application's memory area.
+ </dd>
+ </dl>
+<p>
+ The clipboard holds only one clip object at a time. When an application puts a clip object on
+ the clipboard, the previous clip object disappears.
+</p>
+<p>
+ If you want to allow users to paste data into your application, you don't have to handle all
+ types of data. You can examine the data on the clipboard before you give users the option to
+ paste it. Besides having a certain data form, the clip object also contains metadata that tells
+ you what MIME type or types are available. This metadata helps you decide if your application
+ can do something useful with the clipboard data. For example, if you have an application that
+ primarily handles text you may want to ignore clip objects that contain a URI or Intent.
+</p>
+<p>
+ You may also want to allow users to paste text regardless of the form of data on the
+ clipboard. To do this, you can force the clipboard data into a text representation, and then
+ paste this text. This is described in the section <a href="#CoerceToText">Coercing the
+ clipboard to text</a>.
+</p>
+<h2 id="ClipboardClasses">Clipboard Classes</h2>
+<p>
+ This section describes the classes used by the clipboard framework.
+</p>
+<h3 id="ClipboardManager">ClipboardManager</h3>
+<p>
+ In the Android system, the system clipboard is represented by the global
+ {@link android.content.ClipboardManager} class. You do not instantiate this
+ class directly; instead, you get a reference to it by invoking
+ {@link android.content.Context#getSystemService(String) getSystemService(CLIPBOARD_SERVICE)}.
+</p>
+<h3 id="ClipClasses">ClipData, ClipData.Item, and ClipDescription</h3>
+<p>
+ To add data to the clipboard, you create a {@link android.content.ClipData} object that
+ contains both a description of the data and the data itself. The clipboard holds only one
+ {@link android.content.ClipData} at a time. A {@link android.content.ClipData} contains a
+ {@link android.content.ClipDescription} object and one or more
+ {@link android.content.ClipData.Item} objects.
+</p>
+<p>
+ A {@link android.content.ClipDescription} object contains metadata about the clip. In
+ particular, it contains an array of available MIME types for the clip's data. When you put a
+ clip on the clipboard, this array is available to pasting applications, which can examine it to
+ see if they can handle any of available the MIME types.
+</p>
+<p>
+ A {@link android.content.ClipData.Item} object contains the text, URI, or Intent data:
+</p>
+<dl>
+ <dt>Text</dt>
+ <dd>
+ A {@link java.lang.CharSequence}.
+ </dd>
+ <dt>URI</dt>
+ <dd>
+ A {@link android.net.Uri}. This usually contains a content provider URI, although any
+ URI is allowed. The application that provides the data puts the URI on the clipboard.
+ Applications that want to paste the data get the URI from the clipboard and use it to
+ access the content provider (or other data source) and retrieve the data.
+ </dd>
+ <dt>Intent</dt>
+ <dd>
+ An {@link android.content.Intent}. This data type allows you to copy an application shortcut
+ to the clipboard. Users can then paste the shortcut into their applications for later use.
+ </dd>
+</dl>
+<p>
+ You can add more than one {@link android.content.ClipData.Item} object to a clip. This allows
+ users to copy and paste multiple selections as a single clip. For example, if you have a list
+ widget that allows the user to select more than one item at a time, you can copy all the items
+ to the clipboard at once. To do this, you create a separate
+ {@link android.content.ClipData.Item} for each list item, and then you add the
+ {@link android.content.ClipData.Item} objects to the {@link android.content.ClipData} object.
+</p>
+<h3 id="ClipDataMethods">ClipData convenience methods</h3>
+<p>
+ The {@link android.content.ClipData} class provides static convenience methods for creating
+ a {@link android.content.ClipData} object with a single {@link android.content.ClipData.Item}
+ object and a simple {@link android.content.ClipDescription} object:
+</p>
+<dl>
+ <dt>
+{@link android.content.ClipData#newPlainText(CharSequence,CharSequence) newPlainText(label, text)}
+ </dt>
+ <dd>
+ Returns a {@link android.content.ClipData} object whose single
+ {@link android.content.ClipData.Item} object contains a text string. The
+ {@link android.content.ClipDescription} object's label is set to <code>label</code>.
+ The single MIME type in {@link android.content.ClipDescription} is
+ {@link android.content.ClipDescription#MIMETYPE_TEXT_PLAIN}.
+ <p>
+ Use
+{@link android.content.ClipData#newPlainText(CharSequence,CharSequence) newPlainText()}
+ to create a clip from a text string.
+ </dd>
+ <dt>
+{@link android.content.ClipData#newUri(ContentResolver, CharSequence, Uri) newUri(resolver, label, URI)}
+ </dt>
+ <dd>
+ Returns a {@link android.content.ClipData} object whose single
+ {@link android.content.ClipData.Item} object contains a URI. The
+ {@link android.content.ClipDescription} object's label is set to <code>label</code>.
+ If the URI is a content URI ({@link android.net.Uri#getScheme() Uri.getScheme()} returns
+ <code>content:</code>), the method uses the {@link android.content.ContentResolver} object
+ provided in <code>resolver</code> to retrieve the available MIME types from the
+ content provider and store them in {@link android.content.ClipDescription}. For a URI that
+ is not a <code>content:</code> URI, the method sets the MIME type to
+ {@link android.content.ClipDescription#MIMETYPE_TEXT_URILIST}.
+ <p>
+ Use
+{@link android.content.ClipData#newUri(ContentResolver, CharSequence, Uri) newUri()}
+ to create a clip from a URI, particularly a <code>content:</code> URI.
+ </p>
+ </dd>
+ <dt>
+ {@link android.content.ClipData#newIntent(CharSequence, Intent) newIntent(label, intent)}
+ </dt>
+ <dd>
+ Returns a {@link android.content.ClipData} object whose single
+ {@link android.content.ClipData.Item} object contains an {@link android.content.Intent}.
+ The {@link android.content.ClipDescription} object's label is set to <code>label</code>.
+ The MIME type is set to {@link android.content.ClipDescription#MIMETYPE_TEXT_INTENT}.
+ <p>
+ Use
+{@link android.content.ClipData#newIntent(CharSequence, Intent) newIntent()}
+ to create a clip from an Intent object.
+ </dd>
+</dl>
+<h3 id="CoerceToText">Coercing the clipboard data to text</h3>
+<p>
+ Even if your application only handles text, you can copy non-text data from the
+ clipboard by converting it with the method
+ {@link android.content.ClipData.Item#coerceToText(Context) ClipData.Item.coerceToText()}.
+</p>
+<p>
+ This method converts the data in {@link android.content.ClipData.Item} to text and
+ returns a {@link java.lang.CharSequence}. The value that
+ {@link android.content.ClipData.Item#coerceToText(Context) ClipData.Item.coerceToText()}
+ returns is based on the form of data in {@link android.content.ClipData.Item}:
+</p>
+<dl>
+ <dt><em>Text</em></dt>
+ <dd>
+ If {@link android.content.ClipData.Item} is text
+ ({@link android.content.ClipData.Item#getText()} is not null),
+ {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} returns the
+ text.
+ </dd>
+ <dt><em>URI</em></dt>
+ <dd>
+ If {@link android.content.ClipData.Item} is a URI
+ ({@link android.content.ClipData.Item#getUri()} is not null),
+ {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} tries to use
+ it as a content URI:
+ <ul>
+ <li>
+ If the URI is a content URI and the provider can return a text stream,
+ {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} returns
+ a text stream.
+ </li>
+ <li>
+ If the URI is a content URI but the provider does not offer a text stream,
+ {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} returns
+ a representation of the URI. The representation is the same as that returned by
+ {@link android.net.Uri#toString() Uri.toString()}.
+ </li>
+ <li>
+ If the URI is not a content URI,
+ {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} returns
+ a representation of the URI. The representation is the same as that returned by
+ {@link android.net.Uri#toString() Uri.toString()}.
+ </li>
+ </ul>
+ </dd>
+ <dt><em>Intent</em></dt>
+ <dd>
+ If {@link android.content.ClipData.Item} is an Intent
+ ({@link android.content.ClipData.Item#getIntent()} is not null),
+ {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} converts it to
+ an Intent URI and returns it. The representation is the same as that returned by
+ {@link android.content.Intent#toUri(int) Intent.toUri(URI_INTENT_SCHEME)}.
+ </dd>
+</dl>
+<p>
+ The clipboard framework is summarized in Figure 1. To copy data, an application puts a
+ {@link android.content.ClipData} object on the {@link android.content.ClipboardManager} global
+ clipboard. The {@link android.content.ClipData} contains one or more
+ {@link android.content.ClipData.Item} objects and one
+ {@link android.content.ClipDescription} object. To paste data, an application gets the
+ {@link android.content.ClipData}, gets its MIME type from the
+ {@link android.content.ClipDescription}, and gets the data either from
+ the {@link android.content.ClipData.Item} or from the content provider referred to by
+ {@link android.content.ClipData.Item}.
+</p>
+ <a name="framework"></a>
+ <img
+ src="{@docRoot}images/ui/clipboard/copy_paste_framework.png"
+ alt="A block diagram of the copy and paste framework" height="400px" id="figure1" />
+<p class="img-caption">
+ <strong>Figure 1.</strong> The Android clipboard framework
+</p>
+<h2 id="Copying">Copying to the Clipboard</h2>
+<p>
+ As described previously, to copy data to the clipboard you get a handle to the global
+ {@link android.content.ClipboardManager} object, create a {@link android.content.ClipData}
+ object, add a {@link android.content.ClipDescription} and one or more
+ {@link android.content.ClipData.Item} objects to it, and add the finished
+ {@link android.content.ClipData} object to the {@link android.content.ClipboardManager} object.
+ This is described in detail in the following procedure:
+</p>
+<ol>
+ <li>
+ If you are copying data using a content URI, set up a content
+ provider.
+ <p>
+ The <a href="{@docRoot}resources/samples/NotePad/index.html">
+ Note Pad</a> sample application is an example of using a content provider for
+ copying and pasting. The
+<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NotePadProvider.html">
+ NotePadProvider</a> class implements the content provider. The
+<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NotePad.html">
+ NotePad</a> class defines a contract between the provider and other applications,
+ including the supported MIME types.
+ </p>
+ </li>
+ <li>
+ Get the system clipboard:
+<pre>
+
+...
+
+// if the user selects copy
+case R.id.menu_copy:
+
+// Gets a handle to the clipboard service.
+ClipboardManager clipboard = (ClipboardManager)
+ getSystemService(Context.CLIPBOARD_SERVICE);
+</pre>
+ </li>
+ <li>
+ <p>
+ Copy the data to a new {@link android.content.ClipData} object:
+ </p>
+ <ul>
+ <li>
+ <h4>For text</h4>
+<pre>
+// Creates a new text clip to put on the clipboard
+ClipData clip = ClipData.newPlainText("simple text","Hello, World!");
+</pre>
+ </li>
+ <li>
+ <h4>For a URI</h4>
+ <p>
+ This snippet constructs a URI by encoding a record ID onto the content URI
+ for the provider. This technique is covered in more detail
+ in the section <a href="#Encoding">Encoding an identifier on the URI</a>:
+ </p>
+<pre>
+// Creates a Uri based on a base Uri and a record ID based on the contact's last name
+// Declares the base URI string
+private static final String CONTACTS = "content://com.example.contacts";
+
+// Declares a path string for URIs that you use to copy data
+private static final String COPY_PATH = "/copy";
+
+// Declares the Uri to paste to the clipboard
+Uri copyUri = Uri.parse(CONTACTS + COPY_PATH + "/" + lastName);
+
+...
+
+// Creates a new URI clip object. The system uses the anonymous getContentResolver() object to
+// get MIME types from provider. The clip object's label is "URI", and its data is
+// the Uri previously created.
+ClipData clip = ClipData.newUri(getContentResolver(),"URI",copyUri);
+</pre>
+ </li>
+ <li>
+ <h4>For an Intent</h4>
+ <p>
+ This snippet constructs an Intent for an application
+ and then puts it in the clip object:
+ </p>
+<pre>
+// Creates the Intent
+Intent appIntent = new Intent(this, com.example.demo.myapplication.class);
+
+...
+
+// Creates a clip object with the Intent in it. Its label is "Intent" and its data is
+// the Intent object created previously
+ClipData clip = ClipData.newIntent("Intent",appIntent);
+</pre>
+ </li>
+ </ul>
+ </li>
+ <li>
+ Put the new clip object on the clipboard:
+<pre>
+// Set the clipboard's primary clip.
+clipboard.setPrimaryClip(clip);
+</pre>
+ </li>
+</ol>
+<h2 id="Pasting">Pasting from the Clipboard</h2>
+<p>
+ As described previously, you paste data from the clipboard by getting the global clipboard
+ object, getting the clip object, looking at its data, and if possible copying the data from
+ the clip object to your own storage. This section describes in detail how to do this for
+ the three forms of clipboard data.
+</p>
+<h3 id="PastePlainText">Pasting plain text</h3>
+<p>
+ To paste plain text, first get the global clipboard and verify that it can return plain text.
+ Then get the clip object and copy its text to your own storage using
+ {@link android.content.ClipData.Item#getText()}, as described in the following procedure:
+</p>
+<ol>
+ <li>
+ Get the global {@link android.content.ClipboardManager} object using
+ {@link android.content.Context#getSystemService(String) getSystemService(CLIPBOARD_SERVICE)}. Also
+ declare a global variable to contain the pasted text:
+<pre>
+ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+
+String pasteData = "";
+
+</pre>
+ </li>
+ <li>
+ Next, determine if you should enable or disable the "paste" option in the
+ current Activity. You should verify that the clipboard contains a clip and that you
+ can handle the type of data represented by the clip:
+<pre>
+// Gets the ID of the "paste" menu item
+MenuItem mPasteItem = menu.findItem(R.id.menu_paste);
+
+// If the clipboard doesn't contain data, disable the paste menu item.
+// If it does contain data, decide if you can handle the data.
+if (!(clipboard.hasPrimaryClip())) {
+
+ mPasteItem.setEnabled(false);
+
+ } else if (!(clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))) {
+
+ // This disables the paste menu item, since the clipboard has data but it is not plain text
+ mPasteItem.setEnabled(false);
+ } else {
+
+ // This enables the paste menu item, since the clipboard contains plain text.
+ mPasteItem.setEnabled(true);
+ }
+}
+</pre>
+ </li>
+ <li>
+ Copy the data from the clipboard. This point in the program is only reachable if the
+ "paste" menu item is enabled, so you can assume that the clipboard contains
+ plain text. You do not yet know if it contains a text string or a URI that points to plain
+ text. The following snippet tests this, but it only shows the code for handling plain text:
+<pre>
+// Responds to the user selecting "paste"
+case R.id.menu_paste:
+
+// Examines the item on the clipboard. If getText() does not return null, the clip item contains the
+// text. Assumes that this application can only handle one item at a time.
+ ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
+
+// Gets the clipboard as text.
+pasteData = item.getText();
+
+// If the string contains data, then the paste operation is done
+if (pasteData != null) {
+ return;
+
+// The clipboard does not contain text. If it contains a URI, attempts to get data from it
+} else {
+ Uri pasteUri = item.getUri();
+
+ // If the URI contains something, try to get text from it
+ if (pasteUri != null) {
+
+ // calls a routine to resolve the URI and get data from it. This routine is not
+ // presented here.
+ pasteData = resolveUri(Uri);
+ return;
+ } else {
+
+ // Something is wrong. The MIME type was plain text, but the clipboard does not contain either
+ // text or a Uri. Report an error.
+ Log.e("Clipboard contains an invalid data type");
+ return;
+ }
+}
+</pre>
+ </li>
+</ol>
+<h3 id="PasteContentUri">Pasting data from a content URI</h3>
+<p>
+ If the {@link android.content.ClipData.Item} object contains a content URI and you
+ have determined that you can handle one of its MIME types, create a
+ {@link android.content.ContentResolver} and then call the appropriate content provider
+ method to retrieve the data.
+</p>
+<p>
+ The following procedure describes how to get data from a content provider based on a
+ content URI on the clipboard. It checks that a MIME type that the application can use
+ is available from the provider:
+</p>
+<ol>
+ <li>
+ Declare a global variable to contain the MIME type:
+<pre>
+// Declares a MIME type constant to match against the MIME types offered by the provider
+public static final String MIME_TYPE_CONTACT = "vnd.android.cursor.item/vnd.example.contact"
+</pre>
+ </li>
+ <li>
+ Get the global clipboard. Also get a content resolver so you can access the content
+ provider:
+<pre>
+// Gets a handle to the Clipboard Manager
+ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+
+// Gets a content resolver instance
+ContentResolver cr = getContentResolver();
+</pre>
+ </li>
+ <li>
+ Get the primary clip from the clipboard, and get its contents as a URI:
+<pre>
+// Gets the clipboard data from the clipboard
+ClipData clip = clipboard.getPrimaryClip();
+
+if (clip != null) {
+
+ // Gets the first item from the clipboard data
+ ClipData.Item item = clip.getItemAt(0);
+
+ // Tries to get the item's contents as a URI
+ Uri pasteUri = item.getUri();
+</pre>
+ </li>
+ <li>
+ Test to see if the URI is a content URI by calling
+ {@link android.content.ContentResolver#getType(Uri) getType(Uri)}. This method returns
+ null if <code>Uri</code> does not point to a valid content provider:
+<pre>
+ // If the clipboard contains a URI reference
+ if (pasteUri != null) {
+
+ // Is this a content URI?
+ String uriMimeType = cr.getType(pasteUri);
+</pre>
+ </li>
+ <li>
+ Test to see if the content provider supports a MIME type that the current application
+ understands. If it does, call
+ {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ ContentResolver.query()} to get the data. The return value is a
+ {@link android.database.Cursor}:
+<pre>
+ // If the return value is not null, the Uri is a content Uri
+ if (uriMimeType != null) {
+
+ // Does the content provider offer a MIME type that the current application can use?
+ if (uriMimeType.equals(MIME_TYPE_CONTACT)) {
+
+ // Get the data from the content provider.
+ Cursor pasteCursor = cr.query(uri, null, null, null, null);
+
+ // If the Cursor contains data, move to the first record
+ if (pasteCursor != null) {
+ if (pasteCursor.moveToFirst()) {
+
+ // get the data from the Cursor here. The code will vary according to the
+ // format of the data model.
+ }
+ }
+
+ // close the Cursor
+ pasteCursor.close();
+ }
+ }
+ }
+}
+</pre>
+ </li>
+</ol>
+<h3 id="PasteIntent">Pasting an Intent</h3>
+<p>
+ To paste an Intent, first get the global clipboard. Examine the
+ {@link android.content.ClipData.Item} object to see if it contains an Intent. Then call
+ {@link android.content.ClipData.Item#getIntent()} to copy the Intent to your own storage.
+ The following snippet demonstrates this:
+</p>
+<pre>
+// Gets a handle to the Clipboard Manager
+ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+
+// Checks to see if the clip item contains an Intent, by testing to see if getIntent() returns null
+Intent pasteIntent = clipboard.getPrimaryClip().getItemAt(0).getIntent();
+
+if (pasteIntent != null) {
+
+ // handle the Intent
+
+} else {
+
+ // ignore the clipboard, or issue an error if your application was expecting an Intent to be
+ // on the clipboard
+}
+</pre>
+<h2 id="Provider">Using Content Providers to Copy Complex Data</h2>
+<p>
+ Content providers support copying complex data such as database records or file streams.
+ To copy the data, you put a content URI on the clipboard. Pasting applications then get this
+ URI from the clipboard and use it to retrieve database data or file stream descriptors.
+</p>
+<p>
+ Since the pasting application only has the content URI for your data, it needs to know which
+ piece of data to retrieve. You can provide this information by encoding an identifier for the
+ data on the URI itself, or you can provide a unique URI that will return the data you want to
+ copy. Which technique you choose depends on the organization of your data.
+</p>
+<p>
+ The following sections describe how to set up URIs, how to provide complex data, and how to
+ provide file streams. The descriptions assume that you are familiar with the general principles
+ of content provider design.
+</p>
+<h3 id="Encoding">Encoding an identifier on the URI</h3>
+<p>
+ A useful technique for copying data to the clipboard with a URI is to encode an identifier for
+ the data on the URI itself. Your content provider can then get the identifier from the URI and
+ use it to retrieve the data. The pasting application doesn't have to know that the identifier
+ exists; all it has to do is get your "reference" (the URI plus the identifier) from
+ the clipboard, give it your content provider, and get back the data.
+</p>
+<p>
+ You usually encode an identifier onto a content URI by concatenating it to the end of the URI.
+ For example, suppose you define your provider URI as the following string:
+</p>
+<pre>
+"content://com.example.contacts"
+</pre>
+<p>
+ If you want to encode a name onto this URI, you would use the following snippet:
+</p>
+<pre>
+String uriString = "content://com.example.contacts" + "/" + "Smith"
+
+// uriString now contains content://com.example.contacts/Smith.
+
+// Generates a uri object from the string representation
+Uri copyUri = Uri.parse(uriString);
+</pre>
+<p>
+ If you are already using a content provider, you may want to add a new URI path that indicates
+ the URI is for copying. For example, suppose you already have the following URI paths:
+</p>
+<pre>
+"content://com.example.contacts"/people
+"content://com.example.contacts"/people/detail
+"content://com.example.contacts"/people/images
+</pre>
+<p>
+ You could add another path that is specific to copy URIs:
+</p>
+<pre>
+"content://com.example.contacts/copying"
+</pre>
+<p>
+ You could then detect a "copy" URI by pattern-matching and handle it with code that
+ is specific for copying and pasting.
+</p>
+<p>
+ You normally use the encoding technique if you're already using a content provider, internal
+ database, or internal table to organize your data. In these cases, you have multiple pieces of
+ data you want to copy, and presumably a unique identifier for each piece. In response to a
+ query from the pasting application, you can look up the data by its identifier and return it.
+</p>
+<p>
+ If you don't have multiple pieces of data, then you probably don't need to encode an identifier.
+ You can simply use a URI that is unique to your provider. In response to a query, your provider
+ would return the data it currently contains.
+</p>
+<p>
+ Getting a single record by ID is used in the
+ <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> sample application to
+ open a note from the notes list. The sample uses the <code>_id</code> field from an SQL
+ database, but you can have any numeric or character identifier you want.
+</p>
+<h3 id="Records">Copying data structures</h3>
+<p>
+ You set up a content provider for copying and pasting complex data as a subclass of the
+ {@link android.content.ContentProvider} component. You should also encode the URI you put on
+ the clipboard so that it points to the exact record you want to provide. In addition, you
+ have to consider the existing state of your application:
+</p>
+<ul>
+ <li>
+ If you already have a content provider, you can add to its functionality. You may only
+ need to modify its
+{@link android.content.ContentResolver#query(Uri, String[], String, String[], String) query()}
+ method to handle URIs coming from applications that want to paste data. You will
+ probably want to modify the method to handle a "copy" URI pattern.
+ </li>
+ <li>
+ If your application maintains an internal database, you may
+ want to move this database into a content provider to facilitate copying from it.
+ </li>
+ <li>
+ If you are not currently using a database, you can implement a simple content provider
+ whose sole purpose is to offer data to applications that are pasting from the
+ clipboard.
+ </li>
+</ul>
+<p>
+In the content provider, you will want to override at least the following methods:
+</p>
+<dl>
+ <dt>
+{@link android.content.ContentResolver#query(Uri, String[], String, String[], String) query()}
+ </dt>
+ <dd>
+ Pasting applications will assume that they can get your data by using this method with
+ the URI you put on the clipboard. To support copying, you should have this method
+ detect URIs that contain a special "copy" path. Your application can then
+ create a "copy" URI to put on the clipboard, containing the copy path and
+ a pointer to the exact record you want to copy.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#getType(Uri) getType()}
+ </dt>
+ <dd>
+ This method should return the MIME type or types for the data you intend to copy. The method
+ {@link android.content.ClipData#newUri(ContentResolver, CharSequence, Uri) newUri()} calls
+ {@link android.content.ContentProvider#getType(Uri) getType()} in order to put the MIME
+ types into the new {@link android.content.ClipData} object.
+ <p>
+ MIME types for complex data are described in the topic
+ <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
+ </p>
+ </dd>
+</dl>
+<p>
+ Notice that you don't have to have any of the other content provider methods such as
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} or
+ {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[]) update()}.
+ A pasting application only needs to get your supported MIME types and copy data from your
+ provider. If you already have these methods, they won't interfere with copy operations.
+</p>
+<p>
+ The following snippets demonsrate how to set up your application to copy complex data:
+</p>
+<ol>
+ <li>
+ <p>
+ In the global constants for your application,
+ declare a base URI string and a path that identifies URI strings you are
+ using to copy data. Also declare a MIME type for the copied data:
+ </p>
+<pre>
+// Declares the base URI string
+private static final String CONTACTS = "content://com.example.contacts";
+
+// Declares a path string for URIs that you use to copy data
+private static final String COPY_PATH = "/copy";
+
+// Declares a MIME type for the copied data
+public static final String MIME_TYPE_CONTACT = "vnd.android.cursor.item/vnd.example.contact"
+</pre>
+ </li>
+ <li>
+ In the Activity from which users copy data,
+ set up the code to copy data to the clipboard. In response to a copy request, put
+ the URI on the clipboard:
+<pre>
+public class MyCopyActivity extends Activity {
+
+ ...
+
+// The user has selected a name and is requesting a copy.
+case R.id.menu_copy:
+
+ // Appends the last name to the base URI
+ // The name is stored in "lastName"
+ uriString = CONTACTS + COPY_PATH + "/" + lastName;
+
+ // Parses the string into a URI
+ Uri copyUri = Uri.parse(uriString);
+
+ // Gets a handle to the clipboard service.
+ ClipboardManager clipboard = (ClipboardManager)
+ getSystemService(Context.CLIPBOARD_SERVICE);
+
+ ClipData clip = ClipData.newUri(getContentResolver(), "URI", copyUri);
+
+ // Set the clipboard's primary clip.
+ clipboard.setPrimaryClip(clip);
+</pre>
+ </li>
+
+ <li>
+ <p>
+ In the global scope of your content provider, create a URI matcher and add a URI
+ pattern that will match URIs you put on the clipboard:
+ </p>
+<pre>
+public class MyCopyProvider extends ContentProvider {
+
+ ...
+
+// A Uri Match object that simplifies matching content URIs to patterns.
+private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+// An integer to use in switching based on the incoming URI pattern
+private static final int GET_SINGLE_CONTACT = 0;
+
+...
+
+// Adds a matcher for the content URI. It matches
+// "content://com.example.contacts/copy/*"
+sUriMatcher.addURI(CONTACTS, "names/*", GET_SINGLE_CONTACT);
+</pre>
+ </li>
+ <li>
+ <p>
+ Set up the
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) query()}
+ method. This method can handle different URI patterns, depending on how you code it, but
+ only the pattern for the clipboard copying operation is shown:
+ </p>
+<pre>
+// Sets up your provider's query() method.
+public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+
+ ...
+
+ // Switch based on the incoming content URI
+ switch (sUriMatcher.match(uri)) {
+
+ case GET_SINGLE_CONTACT:
+
+ // query and return the contact for the requested name. Here you would decode
+ // the incoming URI, query the data model based on the last name, and return the result
+ // as a Cursor.
+
+ ...
+
+}
+</pre>
+ </li>
+ <li>
+ <p>
+ Set up the {@link android.content.ContentProvider#getType(Uri) getType()} method to
+ return an appropriate MIME type for copied data:
+ </p>
+<pre>
+// Sets up your provider's getType() method.
+public String getType(Uri uri) {
+
+ ...
+
+ switch (sUriMatcher.match(uri)) {
+
+ case GET_SINGLE_CONTACT:
+
+ return (MIME_TYPE_CONTACT);
+</pre>
+ </li>
+</ol>
+<p>
+ The section <a href="#PasteContentUri">Pasting data from a content URI</a>
+ describes how to get a content URI from the clipboard and use it to get and paste data.
+</p>
+<h3 id="Streams">Copying data streams</h3>
+<p>
+ You can copy and paste large amounts of text and binary data as streams. The data can have
+ forms such as the following:
+</p>
+ <ul>
+ <li>
+ Files stored on the actual device.
+ </li>
+ <li>
+ Streams from sockets.
+ </li>
+ <li>
+ Large amounts of data stored in a provider's underlying database system.
+ </li>
+ </ul>
+<p>
+ A content provider for data streams provides access to its data with a file descriptor object
+ such as {@link android.content.res.AssetFileDescriptor} instead of a
+ {@link android.database.Cursor} object. The pasting application reads the data stream using
+ this file descriptor.
+</p>
+<p>
+ To set up your application to copy a data stream with a provider, follow these steps:
+</p>
+<ol>
+ <li>
+ Set up a content URI for the data stream you are putting on the clipboard. Options
+ for doing this include the following:
+ <ul>
+ <li>
+ Encode an identifier for the data stream onto the URI,
+ as described in the section
+ <a href="#Encoding">Encoding an identifier on the URI</a>, and then maintain a
+ table in your provider that contains identifiers and the corresponding stream name.
+ </li>
+ <li>
+ Encode the stream name directly on the URI.
+ </li>
+ <li>
+ Use a unique URI that always returns the current stream from the provider. If you
+ use this option, you have to remember to update your provider to point to a
+ different stream whenever you copy the stream to the clipboard via the URI.
+ </li>
+ </ul>
+ </li>
+ <li>
+ Provide a MIME type for each type of data stream you plan to offer. Pasting applications
+ need this information to determine if they can paste the data on the clipboard.
+ </li>
+ <li>
+ Implement one of the {@link android.content.ContentProvider} methods that returns
+ a file descriptor for a stream. If you encode identifiers on the content URI, use this
+ method to determine which stream to open.
+ </li>
+ <li>
+ To copy the data stream to the clipboard, construct the content URI and place it
+ on the clipboard.
+ </li>
+</ol>
+<p>
+ To paste a data stream, an application gets the clip from the clipboard, gets the URI, and
+ uses it in a call to a {@link android.content.ContentResolver} file descriptor method that
+ opens the stream. The {@link android.content.ContentResolver} method calls the corresponding
+ {@link android.content.ContentProvider} method, passing it the content URI. Your provider
+ returns the file descriptor to {@link android.content.ContentResolver} method. The pasting
+ application then has the responsibility to read the data from the stream.
+</p>
+<p>
+ The following list shows the most important file descriptor methods for a content provider.
+ Each of these has a corresponding {@link android.content.ContentResolver} method with the
+ string "Descriptor" appended to the method name; for example, the
+ {@link android.content.ContentResolver} analog of
+ {@link android.content.ContentProvider#openAssetFile(Uri, String) openAssetFile()} is
+{@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String) openAssetFileDescriptor()}:
+</p>
+<dl>
+ <dt>
+{@link android.content.ContentProvider#openTypedAssetFile(Uri,String,Bundle) openTypedAssetFile()}
+ </dt>
+ <dd>
+ This method should return an asset file descriptor, but only if the provided MIME type is
+ supported by the provider. The caller (the application doing the pasting) provides a MIME
+ type pattern. The content provider (of the application that has copied a URI to the
+ clipboard) returns an {@link android.content.res.AssetFileDescriptor} file handle if it
+ can provide that MIME type, or throws an exception if it can not.
+ <p>
+ This method handles subsections of files. You can use it to read assets that the
+ content provider has copied to the clipboard.
+ </p>
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#openAssetFile(Uri, String) openAssetFile()}
+ </dt>
+ <dd>
+ This method is a more general form of
+{@link android.content.ContentProvider#openTypedAssetFile(Uri,String,Bundle) openTypedAssetFile()}.
+ It does not filter for allowed MIME types, but it can read subsections of files.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#openFile(Uri, String) openFile()}
+ </dt>
+ <dd>
+ This is a more general form of
+ {@link android.content.ContentProvider#openAssetFile(Uri, String) openAssetFile()}. It can't
+ read subsections of files.
+ </dd>
+</dl>
+<p>
+ You can optionally use the
+{@link android.content.ContentProvider#openPipeHelper(Uri, String, Bundle, T, ContentProvider.PipeDataWriter) openPipeHelper()}
+ method with your file descriptor method. This allows the pasting application to read the
+ stream data in a background thread using a pipe. To use this method, you need to implement the
+ {@link android.content.ContentProvider.PipeDataWriter} interface. An example of doing this is
+ given in the <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> sample
+ application, in the <code>openTypedAssetFile()</code> method of
+ <code>NotePadProvider.java</code>.
+</p>
+<h2 id="DataDesign">Designing Effective Copy/Paste Functionality</h2>
+<p>
+ To design effective copy and paste functionality for your application, remember these
+ points:
+</p>
+ <ul>
+ <li>
+ At any time, there is only one clip on the clipboard. A new copy operation by
+ any application in the system overwrites the previous clip. Since the user may
+ navigate away from your application and do a copy before returning, you can't assume
+ that the clipboard contains the clip that the user previously copied in <em>your</em>
+ application.
+ </li>
+ <li>
+ The intended purpose of multiple {@link android.content.ClipData.Item}
+ objects per clip is to support copying and pasting of multiple selections rather than
+ different forms of reference to a single selection. You usually want all of the
+ {@link android.content.ClipData.Item} objects in a clip to have the same form, that is,
+ they should all be simple text, content URI, or {@link android.content.Intent}, but not
+ a mixture.
+ </li>
+ <li>
+ When you provide data, you can offer different MIME representations. Add the MIME types
+ you support to the {@link android.content.ClipDescription}, and then
+ implement the MIME types in your content provider.
+ </li>
+ <li>
+ When you get data from the clipboard, your application is responsible for checking the
+ available MIME types and then deciding which one, if any, to use. Even if there is a
+ clip on the clipboard and the user requests a paste, your application is not required
+ to do the paste. You <em>should</em> do the paste if the MIME type is compatible. You
+ may choose to coerce the data on the clipboard to text using
+ {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} if you
+ choose. If your application supports more than one of the available MIME types, you can
+ allow the user to choose which one to use.
+ </li>
+ </ul>
diff --git a/docs/html/guide/topics/graphics/animation.jd b/docs/html/guide/topics/graphics/animation.jd
index 83a4e1d..cd74efa 100644
--- a/docs/html/guide/topics/graphics/animation.jd
+++ b/docs/html/guide/topics/graphics/animation.jd
@@ -1,40 +1,37 @@
-page.title=Animation
+page.title=Property Animation
@jd:body
- <div id="qv-wrapper">
+
+ <div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
- <li>
- <a href="#property-animation">Property Animation</a>
-
+ <li><a href="#what">What is Property Animation?</a>
<ol>
+ <li><a href="#how">How property animation works</a></li>
+ </ol>
+ </li>
+
<li><a href="#value-animator">Animating with ValueAnimator</a></li>
<li><a href="#object-animator">Animating with ObjectAnimator</a></li>
+ <li><a href="#choreography">Choreographing Multiple Animations with
+ AnimatorSet</a></li>
+
+ <li><a href="#listeners">Animation Listeners</a></li>
+
<li><a href="#type-evaluator">Using a TypeEvaluator</a></li>
- <li><a href="#interpolators">Using interpolators</a></li>
+ <li><a href="#interpolators">Using Interpolators</a></li>
- <li><a href="#keyframes">Specifying keyframes</a></li>
+ <li><a href="#keyframes">Specifying Keyframes</a></li>
+ <li><a href="#layout">Animating Layout Changes to ViewGroups</a></li>
- <li><a href="#choreography">Choreographing multiple animations with AnimatorSet</a></li>
+ <li><a href="#views">Animating Views</a></li>
- <li><a href="#declaring-xml">Declaring animations in XML</a></li>
- </ol>
- </li>
-
- <li>
- <a href="#view-animation">View Animation</a>
-
- <ol>
- <li><a href="#tween-animation">Tween animation</a></li>
-
- <li><a href="#frame-animation">Frame animation</a></li>
- </ol>
- </li>
- </ol>
+ <li><a href="#declaring-xml">Declaring Animations in XML</a></li>
+ </ol>
<h2>Key classes</h2>
@@ -52,201 +49,504 @@
<h2>Related samples</h2>
<ol>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API Demos</a></li>
+ <li><a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API
+ Demos</a></li>
</ol>
-
</div>
</div>
- <p>The Android system provides a flexible animation system that allows you to animate
- almost anything, either programmatically or declaratively with XML. There are two
- animation systems that you can choose from: <a href="#property-animation">property
- animation</a> and <a href="#view-animation">view animation</a>. You can use whichever
- system that matches your needs, but use only one system for each object that you
- are animating.</p>
-
- <h2 id="property-animation">Property Animation</h2>
-
- <p>Introduced in Android 3.0, the property animation system allows you to animate
- object properties of any type. <code>int</code>, <code>float</code>,
- and hexadecimal color values are supported by default. You can animate any other type by telling the
- system how to calculate the values for that given type.</p>
+ <p>Introduced in Android 3.0, the property animation system is a robust framework that allows you
+ to animate almost anything. Property animation is not confined to objects drawn on the screen.
+ You can define an animation to change any object property over time, regardless of whether it
+ draws to the screen or not.The property animation system also has a few advantages over the view
+ animation system, which makes it more flexible to use.</p>
- <p>The property animation system allows you to define many aspects of an animation,
- such as:</p>
+ <p>The view animation system provides the capability to only animate View objects, so if
+ you wanted to animate non-View objects, you had to implement your own code to do so. The view
+ animation system also was constrained in the fact that it only exposed a few aspects of a View
+ object to animate, such as the scaling and rotation of a View but not the background color for
+ instance.</p>
+
+ <p>Another disadvantage of the view animation system is that it only modified where the
+ View was drawn, and not the actual View itself. For instance, if you animated a button to move
+ across the screen, the button draws correctly, but the actual location where you can click the
+ button does not change, so you have to implement your own logic to handle this. With the property
+ animation system, these constraints are completely removed, and you can animate any property of
+ any object, including View objects, and the object itself is actually modified.</p>
+
+ <p>The view animation system, however, takes less time to setup and requires less code to write.
+ If view animation accomplishes everything that you need to do, or if your existing code already
+ works the way you want, there is no need to use the property animation system.</p>
+
+ <h2 id="what">What is Property Animation?</h2>
+ A property animation changes a property's (a field in
+ an object) value over a specified length of time. To animate something, you specify the
+ object property that you want to animate, such as an object's position on the screen, how long
+ you want to animate it for, and what values you want to animate between. </p>
+
+ <p>The property animation system lets you define the following characteristics of an
+ animation:</p>
<ul>
- <li>Duration</li>
+ <li>Duration: You can specify the duration of an animation. The default length is 300 ms.</li>
- <li>Repeat amount and behavior</li>
+ <li>Time interpolation: You can specify how the values for the property are calculated as a
+ function of the animation's current elapsed time.</li>
- <li>Type of time interpolation</li>
+ <li>Repeat count and behavior: You can specify whether or not to have an animation repeat when
+ it reaches the end of a duration and how many times to repeat the animation. You can also
+ specify whether you want the animation to play back in reverse. Setting it to reverse plays
+ the animation forwards then backwards repeatedly, until the number of repeats is reached.</li>
- <li>Animator sets to play animations together, sequentially, or after specified
- delays</li>
+ <li>Animator sets: You can group animations into logical sets that play together or
+ sequentially or after specified delays.</li>
- <li>Frame refresh delay</li>
-
+ <li>Frame refresh delay: You can specify how often to refresh frames of your animation. The
+ default is set to refresh every 10 ms, but the speed in which your application can refresh frames is
+ ultimately dependent on how busy the system is overall and how fast the system can service the underlying timer.</li>
</ul>
- <p>Most of the property animation system's features can be found in
- {@link android.animation android.animation}. Because the
- <a href="#view-animation">view animation</a> system already
- defines many interpolators in {@link android.view.animation android.view.animation},
- you will use those to define your animation's interpolation in the property animation
- system as well.
- </p>
+ <h3 id="how">How the property animation system works</h3>
- <p>The following items are the main components of the property animation system:</p>
+ <p>First, let's go over how an animation works with a simple example. Figure 1 depicts a
+ hypothetical object that is animated with its <code>x</code> property, which represents its
+ horizontal location on a screen. The duration of the animation is set to 40 ms and the distance
+ to travel is 40 pixels. Every 10 ms, which is the default frame refresh rate, the object moves
+ horizontally by 10 pixels. At the end of 40ms, the animation stops, and the object ends at
+ horizontal position 40. This is an example of an animation with linear interpolation, meaning the
+ object moves at a constant speed.</p><img src="{@docRoot}images/animation/animation-linear.png">
- <dl>
- <dt><strong>Animators</strong></dt>
+ <p class="img-caption"><strong>Figure 1.</strong> Example of a linear animation</p>
- <dd>
- The {@link android.animation.Animator} class provides the basic structure for
- creating animations. You normally do not use this class directly as it only provides
- minimal functionality that must be extended to fully support animating values.
- The following subclasses extend {@link android.animation.Animator}, which you might find more useful:
+ <p>You can also specify animations to have a non-linear interpolation. Figure 2 illustrates a
+ hypothetical object that accelerates at the beginning of the animation, and decelerates at the
+ end of the animation. The object still moves 40 pixels in 40 ms, but non-linearly. In the
+ beginning, this animation accelerates up to the halfway point then decelerates from the
+ halfway point until the end of the animation. As Figure 2 shows, the distance traveled
+ at the beginning and end of the animation is less than in the middle.</p><img src=
+ "{@docRoot}images/animation/animation-nonlinear.png">
- <ul>
- <li>{@link android.animation.ValueAnimator} is the main timing engine for
- property animation and computes the values for the property to be animated.
- {@link android.animation.ValueAnimator} only computes the animation values and is
- not aware of the specific object and property that is being animated or what the
- values might be used for. You must listen for updates to values calculated by the
- {@link android.animation.ValueAnimator} and process the data with your own logic.
- See the section about <a href="#value-animator">Animating with ValueAnimator</a>
- for more information.</li>
+ <p class="img-caption"><strong>Figure 2.</strong> Example of a non-linear animation</p>
- <li>{@link android.animation.ObjectAnimator} is a subclass of {@link
- android.animation.ValueAnimator} and allows you to set a target object and object
- property to animate. This class is aware of the object and property to be
- animated, and updates the property accordingly when it computes a new value for
- the animation. See the section about <a href="#object-animator">
- Animating with ObjectAnimator</a> for more information.</li>
+ <p>Let's take a detailed look at how the important components of the property animation system
+ would calculate animations like the ones illustrated above. Figure 3 depicts how the main classes
+ work with one another.</p><img src="{@docRoot}images/animation/valueanimator.png">
- <li>{@link android.animation.AnimatorSet} provides a mechanism to group
- animations together so that they are rendered in relation to one another. You can
- set animations to play together, sequentially, or after a specified delay.
- See the section about <a href="#choreography">
- Choreographing multiple animations with Animator Sets</a> for more information.</li>
- </ul>
- </dd>
+ <p class="img-caption"><strong>Figure 3.</strong> How animations are calculated</p>
- <dt><strong>Evaluators</strong></dt>
+ <p>The {@link android.animation.ValueAnimator} object keeps track of your animation's timing,
+ such as how long the animation has been running, and the current value of the property that it is
+ animating.</p>
- <dd>
- <p>If you are animating an object property that is <em>not</em> an <code>int</code>,
- <code>float</code>, or color, implement the {@link android.animation.TypeEvaluator}
- interface to specify how to compute the object property's animated values. You give
- a {@link android.animation.TypeEvaluator} the timing data that is provided by an
- {@link android.animation.Animator} class, the animation's start and end value, and
- provide logic that computes the animated values of the property based on this data.</p>
+ <p>The {@link android.animation.ValueAnimator} encapsulates a {@link
+ android.animation.TimeInterpolator}, which defines animation interpolation, and a {@link
+ android.animation.TypeEvaluator}, which defines how to calculate values for the property being
+ animated. For example, in Figure 2, the {@link android.animation.TimeInterpolator} used would be
+ {@link android.view.animation.AccelerateDecelerateInterpolator} and the {@link
+ android.animation.TypeEvaluator} would be {@link android.animation.IntEvaluator}.</p>
- <p>You can also specify a custom {@link android.animation.TypeEvaluator} for
- <code>int</code>, <code>float</code>, and color values as well, if you want to
- process those types differently than the default behavior.</p>
+ <p>To start an animation, create a {@link android.animation.ValueAnimator} and give it the
+ starting and ending values for the property that you want to animate, along with the duration of
+ the animation. When you call {@link android.animation.ValueAnimator#start start()} the animation
+ begins. During the whole animation, the {@link android.animation.ValueAnimator} calculates an <em>elapsed fraction</em>
+ between 0 and 1, based on the duration of the animation and how much time has elapsed. The
+ elapsed fraction represents the percentage of time that the animation has completed, 0 meaning 0%
+ and 1 meaning 100%. For example, in Figure 1, the elapsed fraction at t = 10 ms would be .25
+ because the total duration is t = 40 ms.</p>
- <p>See <a href="#type-evaluator">Using a TypeEvaluator</a> for more information on
- how to write a custom evaluator.</p>
- </dd>
+ <p>When the {@link android.animation.ValueAnimator} is done calculating an elapsed fraction, it
+ calls the {@link android.animation.TimeInterpolator} that is currently set, to calculate an
+ <em>interpolated fraction</em>. An interpolated fraction maps the elapsed fraction to a new
+ fraction that takes into account the time interpolation that is set. For example, in Figure 2,
+ because the animation slowly accelerates, the interpolated fraction, about .15, is less than the
+ elapsed fraction, .25, at t = 10 ms. In Figure 1, the interpolated fraction is always the same as
+ the elapsed fraction.</p>
- <dt><strong>Interpolators</strong></dt>
+ <p>When the interpolated fraction is calculated, {@link android.animation.ValueAnimator} calls
+ the appropriate {@link android.animation.TypeEvaluator}, to calculate the value of the
+ property that you are animating, based on the interpolated fraction, the starting value, and the
+ ending value of the animation. For example, in Figure 2, the interpolated fraction was .15 at t =
+ 10 ms, so the value for the property at that time would be .15 X (40 - 0), or 6.</p>
- <dd>
- <p>A time interpolator defines how specific values in an animation are calculated
- as a function of time. For example, you can specify animations to happen linearly
- across the whole animation, meaning the animation moves evenly the entire time, or
- you can specify animations to use non-linear time, for example, using acceleration
- or deceleration at the beginning or end of the animation.</p>
+ <!-- <p>When the final value is calculated, the {@link android.animation.ValueAnimator} calls the
+ {@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
+ onAnimationUpdate()} method. Implement this callback to obtain the property value by
+ calling {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} and set the
+ value for the property in the object that you are animating. Setting the property doesn't redraw
+ the object on the screen, so you need to call {@link
+ android.view.View#invalidate invalidate()} to refresh the View that the object
+ resides in. If the object is actually a View object, then the system calls {@link
+ android.view.View#invalidate invalidate()} when the property is changed.
+ The system redraws the window and the {@link android.animation.ValueAnimator}
+ repeats the process.</p>-->
- <p>The Android system provides a set of common interpolators in
- {@link android.view.animation android.view.animation}. If none of these suits your needs, you
- can implement the {@link android.animation.TimeInterpolator} interface and create
- your own. See <a href="#interpolators">Using interpolators</a> for more information on
- how to write a custom interpolator.</p>
- </dd>
- </dl>
-
-
<p>The <code>com.example.android.apis.animation</code> package in the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">
- API Demos</a> sample project also provides a good overview and many examples on how to
- use the property animation system.</p>
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API
+ Demos</a> sample project provides many examples on how to use the property
+ animation system.</p>
+ <h2>API Overview</h2>
- <h3>How the property animation system calculates animated values</h3>
+ <p>You can find most of the property animation system's APIs in {@link android.animation
+ android.animation}. Because the view animation system already
+ defines many interpolators in {@link android.view.animation android.view.animation}, you can use
+ those interpolators in the property animation system as well. The following tables describe the main
+ components of the property animation system.</p>
- <p>When you call {@link android.animation.ValueAnimator#start start()} to begin an animation,
- the {@link android.animation.ValueAnimator} calculates
- an <em>elapsed fraction</em> between 0 and 1, based on the duration of the animation
- and how much time has elapsed. The elapsed fraction represents the percentage of time
- that the animation has completed, 0 meaning 0% and 1 meaning 100%. The Animator then
- calls the {@link android.animation.TimeInterpolator} that is currently set,
- to calculate an <em>eased fraction</em>,
- which is a modified value of the elapsed fraction that takes into account the interpolator that
- is set (time interpolation is often referred to as <em>easing</em>). The eased fraction
- is the final value that is used to animate the property.</p>
+ <p>The {@link android.animation.Animator} class provides the basic structure for creating
+ animations. You normally do not use this class directly as it only provides minimal
+ functionality that must be extended to fully support animating values. The following
+ subclasses extend {@link android.animation.Animator}:
+ </p>
+ <p class="table-caption"><strong>Table 1.</strong> Animators</p>
+ <table>
+ <tr>
+ <th>Class</th>
- <p>Once the eased fraction is calculated, {@link android.animation.ValueAnimator} calls
- the appropriate {@link android.animation.TypeEvaluator} to calculate the final value of
- the property that you are animating, based on the eased fraction, the starting value,
- and ending value of the animation.</p>
+ <th>Description</th>
+ </tr>
- <h3 id="value-animator">Animating with ValueAnimator</h3>
+ <tr>
+ <td>{@link android.animation.ValueAnimator}</td>
- <p>The {@link android.animation.ValueAnimator} class lets you animate values of some
- type for the duration of an animation by specifying a set of <code>int</code>,
- <code>float</code>, or color values to animate over and the duration of the animation.
- You obtain a {@link android.animation.ValueAnimator} by calling one of its factory
- methods: {@link android.animation.ValueAnimator#ofInt ofInt()},
- {@link android.animation.ValueAnimator#ofFloat ofFloat()},
- or {@link android.animation.ValueAnimator#ofObject ofObject()}. For example:</p>
-
- <pre>ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
+ <td>The main timing engine for property animation that also computes the values for the
+ property to be animated. It has all of the core functionality that calculates animation
+ values and contains the timing details of each animation, information about whether an
+ animation repeats, listeners that receive update events, and the ability to set custom
+ types to evaluate. There are two pieces to animating properties: calculating the animated
+ values and setting those values on the object and property that is being animated. {@link
+ android.animation.ValueAnimator} does not carry out the second piece, so you must listen
+ for updates to values calculated by the {@link android.animation.ValueAnimator} and
+ modify the objects that you want to animate with your own logic. See the section about
+ <a href="#value-animator">Animating with ValueAnimator</a> for more information.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.ObjectAnimator}</td>
+
+ <td>A subclass of {@link android.animation.ValueAnimator} that allows you to set a target
+ object and object property to animate. This class updates the property accordingly when
+ it computes a new value for the animation. You want to use
+ {@link android.animation.ObjectAnimator} most of the time,
+ because it makes the process of animating values on target objects much easier. However,
+ you sometimes want to use {@link android.animation.ValueAnimator} directly because {@link
+ android.animation.ObjectAnimator} has a few more restrictions, such as requiring specific
+ acessor methods to be present on the target object.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.AnimatorSet}</td>
+
+ <td>Provides a mechanism to group animations together so that they run in
+ relation to one another. You can set animations to play together, sequentially, or after
+ a specified delay. See the section about <a href="#choreography">Choreographing multiple
+ animations with Animator Sets</a> for more information.</td>
+ </tr>
+ </table>
+
+
+ <p>Evaluators tell the property animation system how to calculate values for a given
+ property. They take the timing data that is provided by an {@link android.animation.Animator}
+ class, the animation's start and end value, and calculate the animated values of the property
+ based on this data. The property animation system provides the following evaluators:</p>
+ <p class="table-caption"><strong>Table 2.</strong> Evaluators</p>
+ <table>
+ <tr>
+ <th>Class/Interface</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.IntEvaluator}</td>
+
+ <td>The default evaluator to calculate values for <code>int</code> properties.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.FloatEvaluator}</td>
+
+ <td>The default evaluator to calculate values for <code>float</code> properties.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.ArgbEvaluator}</td>
+
+ <td>The default evaluator to calculate values for color properties that are represented
+ as hexidecimal values.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.TypeEvaluator}</td>
+
+ <td>An interface that allows you to create your own evaluator. If you are animating an
+ object property that is <em>not</em> an <code>int</code>, <code>float</code>, or color,
+ you must implement the {@link android.animation.TypeEvaluator} interface to specify how
+ to compute the object property's animated values. You can also specify a custom {@link
+ android.animation.TypeEvaluator} for <code>int</code>, <code>float</code>, and color
+ values as well, if you want to process those types differently than the default behavior.
+ See the section about <a href="#type-evaluator">Using a TypeEvaluator</a> for more
+ information on how to write a custom evaluator.</td>
+ </tr>
+ </table>
+
+
+
+
+ <p>A time interpolator defines how specific values in an animation are calculated as a
+ function of time. For example, you can specify animations to happen linearly across the whole
+ animation, meaning the animation moves evenly the entire time, or you can specify animations
+ to use non-linear time, for example, accelerating at the beginning and decelerating at the
+ end of the animation. Table 3 describes the interpolators that are contained in {@link
+ android.view.animation android.view.animation}. If none of the provided interpolators suits
+ your needs, implement the {@link android.animation.TimeInterpolator} interface and create your own. See <a href=
+ "#interpolators">Using interpolators</a> for more information on how to write a custom
+ interpolator.</p>
+ <p class="table-caption"><strong>Table 3.</strong> Interpolators</p>
+ <table>
+ <tr>
+ <th>Class/Interface</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.AccelerateDecelerateInterpolator}</td>
+
+ <td>An interpolator whose rate of change starts and ends slowly but accelerates
+ through the middle.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.AccelerateInterpolator}</td>
+
+ <td>An interpolator whose rate of change starts out slowly and then
+ accelerates.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.AnticipateInterpolator}</td>
+
+ <td>An interpolator whose change starts backward then flings forward.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.AnticipateOvershootInterpolator}</td>
+
+ <td>An interpolator whose change starts backward, flings forward and overshoots
+ the target value, then finally goes back to the final value.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.BounceInterpolator}</td>
+
+ <td>An interpolator whose change bounces at the end.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.CycleInterpolator}</td>
+
+ <td>An interpolator whose animation repeats for a specified number of cycles.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.DecelerateInterpolator}</td>
+
+ <td>An interpolator whose rate of change starts out quickly and and then
+ decelerates.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.LinearInterpolator}</td>
+
+ <td>An interpolator whose rate of change is constant.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.OvershootInterpolator}</td>
+
+ <td>An interpolator whose change flings forward and overshoots the last value then
+ comes back.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.TimeInterpolator}</td>
+
+ <td>An interface that allows you to implement your own interpolator.</td>
+ </tr>
+ </table>
+
+ <h2 id="value-animator">Animating with ValueAnimator</h2>
+
+ <p>The {@link android.animation.ValueAnimator} class lets you animate values of some type for the
+ duration of an animation by specifying a set of <code>int</code>, <code>float</code>, or color
+ values to animate through. You obtain a {@link android.animation.ValueAnimator} by calling one of
+ its factory methods: {@link android.animation.ValueAnimator#ofInt ofInt()}, {@link
+ android.animation.ValueAnimator#ofFloat ofFloat()}, or {@link
+ android.animation.ValueAnimator#ofObject ofObject()}. For example:</p>
+ <pre>
+ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.start();
</pre>
- <p>In this code, the {@link android.animation.ValueAnimator} starts
- calculating the values of the animation, between 0 and 1, for
- a duration of 1000 ms, when the <code>start()</code> method runs.</p>
+ <p>In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the
+ animation, between 0 and 1, for a duration of 1000 ms, when the <code>start()</code> method
+ runs.</p>
<p>You can also specify a custom type to animate by doing the following:</p>
-
- <pre>ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
+ <pre>
+ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();
</pre>
- <p>In this code, the {@link android.animation.ValueAnimator} starts
- calculating the values of the animation, between <code>startPropertyValue</code> and
- <code>endPropertyValue</code> using the logic supplied by <code>MyTypeEvaluator</code>
- for a duration of 1000 ms, when the {@link android.animation.ValueAnimator#start start()}
- method runs.</p>
+ <p>In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the
+ animation, between <code>startPropertyValue</code> and <code>endPropertyValue</code> using the
+ logic supplied by <code>MyTypeEvaluator</code> for a duration of 1000 ms, when the {@link
+ android.animation.ValueAnimator#start start()} method runs.</p>
- <p>The previous code snippets, however, do not affect an object, because the {@link
- android.animation.ValueAnimator} does not operate on objects or properties directly. To
- use the results of a {@link android.animation.ValueAnimator}, you must define listeners
- in the {@link android.animation.ValueAnimator} to appropriately handle important events
- during the animation's lifespan, such as frame updates. You can implement the following
- interfaces to create listeners for {@link android.animation.ValueAnimator}:</p>
+ <p>The previous code snippets, however, has no real effect on an object, because the {@link
+ android.animation.ValueAnimator} does not operate on objects or properties directly. The most likely thing
+ that you want to do is modify the objects that you want to animate with these calculated values. You do
+ this by defining listeners in the {@link android.animation.ValueAnimator} to appropriately handle important events
+ during the animation's lifespan, such as frame updates. When implementing the listeners, you can
+ obtain the calculated value for that specific frame refresh by calling {@link
+ android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()}. For more information on listeners,
+ see the section about <a href="#listeners">Animation Listeners</a>.
+
+ <h2 id="object-animator">Animating with ObjectAnimator</h2>
+
+ <p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link
+ android.animation.ValueAnimator} (discussed in the previous section) and combines the timing
+ engine and value computation of {@link android.animation.ValueAnimator} with the ability to
+ animate a named property of a target object. This makes animating any object much easier, as you
+ no longer need to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener},
+ because the animated property updates automatically.</p>
+
+ <p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link
+ android.animation.ValueAnimator}, but you also specify the object and the name of that object's property (as
+ a String) along with the values to animate between:</p>
+ <pre>
+ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
+anim.setDuration(1000);
+anim.start();
+</pre>
+
+ <p>To have the {@link android.animation.ObjectAnimator} update properties correctly, you must do
+ the following:</p>
+
+ <ul>
+ <li>The object property that you are animating must have a setter function (in camel case) in the form of
+ <code>set<propertyName>()</code>. Because the {@link android.animation.ObjectAnimator}
+ automatically updates the property during animation, it must be able to access the property
+ with this setter method. For example, if the property name is <code>foo</code>, you need to
+ have a <code>setFoo()</code> method. If this setter method does not exist, you have three
+ options:
+
+ <ul>
+ <li>Add the setter method to the class if you have the rights to do so.</li>
+
+ <li>Use a wrapper class that you have rights to change and have that wrapper receive the
+ value with a valid setter method and forward it to the original object.</li>
+
+ <li>Use {@link android.animation.ValueAnimator} instead.</li>
+ </ul>
+ </li>
+
+ <li>If you specify only one value for the <code>values...</code> parameter in one of the {@link
+ android.animation.ObjectAnimator} factory methods, it is assumed to be the ending value of the
+ animation. Therefore, the object property that you are animating must have a getter function
+ that is used to obtain the starting value of the animation. The getter function must be in the
+ form of <code>get<propertyName>()</code>. For example, if the property name is
+ <code>foo</code>, you need to have a <code>getFoo()</code> method.</li>
+
+ <li>The getter (if needed) and setter methods of the property that you are animating must
+ operate on the same type as the starting and ending values that you specify to {@link
+ android.animation.ObjectAnimator}. For example, you must have
+ <code>targetObject.setPropName(float)</code> and <code>targetObject.getPropName(float)</code>
+ if you construct the following {@link android.animation.ObjectAnimator}:
+ <pre>
+ObjectAnimator.ofFloat(targetObject, "propName", 1f)
+</pre>
+ </li>
+
+ <li>Depending on what property or object you are animating, you might need to call the {@link
+ android.view.View#invalidate invalidate()} method on a View force the screen to redraw itself with the
+ updated animated values. You do this in the
+ {@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate onAnimationUpdate()}
+ callback. For example, animating the color property of a Drawable object only cause updates to the
+ screen when that object redraws itself. All of the property setters on View, such as
+ {@link android.view.View#setAlpha setAlpha()} and {@link android.view.View#setTranslationX setTranslationX()}
+ invalidate the View properly, so you do not need to invalidate the View when calling these
+ methods with new values. For more information on listeners, see the section about <a href="#listeners">Animation Listeners</a>.
+ </li>
+ </ul>
+
+ <h2 id="choreography">Choreographing Multiple Animations with AnimatorSet</h2>
+
+ <p>In many cases, you want to play an animation that depends on when another animation starts or
+ finishes. The Android system lets you bundle animations together into an {@link
+ android.animation.AnimatorSet}, so that you can specify whether to start animations
+ simultaneously, sequentially, or after a specified delay. You can also nest {@link
+ android.animation.AnimatorSet} objects within each other.</p>
+
+ <p>The following sample code taken from the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
+ Balls</a> sample (modified for simplicity) plays the following {@link android.animation.Animator}
+ objects in the following manner:</p>
+
+ <ol>
+ <li>Plays <code>bounceAnim</code>.</li>
+
+ <li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>, <code>stretchAnim1</code>, and
+ <code>stretchAnim2</code> at the same time.</li>
+
+ <li>Plays <code>bounceBackAnim</code>.</li>
+
+ <li>Plays <code>fadeAnim</code>.</li>
+ </ol>
+ <pre>
+AnimatorSet bouncer = new AnimatorSet();
+bouncer.play(bounceAnim).before(squashAnim1);
+bouncer.play(squashAnim1).with(squashAnim2);
+bouncer.play(squashAnim1).with(stretchAnim1);
+bouncer.play(squashAnim1).with(stretchAnim2);
+bouncer.play(bounceBackAnim).after(stretchAnim2);
+ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+AnimatorSet animatorSet = new AnimatorSet();
+animatorSet.play(bouncer).before(fadeAnim);
+animatorSet.start();
+</pre>
+
+ <p>For a more complete example on how to use animator sets, see the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
+ Balls</a> sample in APIDemos.</p>
+
+<h2 id="listeners">Animation Listeners</h2>
+<p>
+You can listen for important events during an animation's duration with the listeners described below.
+</p>
<ul>
<li>{@link android.animation.Animator.AnimatorListener}
<ul>
- <li>{@link android.animation.Animator.AnimatorListener#onAnimationStart
- onAnimationStart()} - Called when the animation starts</li>
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationStart onAnimationStart()}
+ - Called when the animation starts.</li>
- <li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd
- onAnimationEnd()} - Called when the animation ends.</li>
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()} -
+ Called when the animation ends.</li>
<li>{@link android.animation.Animator.AnimatorListener#onAnimationRepeat
onAnimationRepeat()} - Called when the animation repeats itself.</li>
<li>{@link android.animation.Animator.AnimatorListener#onAnimationCancel
- onAnimationCancel()} - Called when the animation is canceled.</li>
+ onAnimationCancel()} - Called when the animation is canceled. A cancelled animation
+ also calls {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()},
+ regardless of how they were ended.</li>
</ul>
</li>
@@ -254,167 +554,173 @@
<ul>
<li>
- <p>{@link
- android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
- onAnimationUpdate()} - called on every frame of the animation.
- Listen to this event to use the calculated values generated by
- {@link android.animation.ValueAnimator} during an animation. To use the value,
- query the {@link android.animation.ValueAnimator} object passed into the event
- to get the current animated value with the
- {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method.</p>
+ <p>{@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
+ onAnimationUpdate()} - called on every frame of the animation. Listen to this event to
+ use the calculated values generated by {@link android.animation.ValueAnimator} during an
+ animation. To use the value, query the {@link android.animation.ValueAnimator} object
+ passed into the event to get the current animated value with the {@link
+ android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method. Implementing this
+ listener is required if you use {@link android.animation.ValueAnimator}. </p>
- <p>If you are animating your own custom object (not View objects), this
- callback must also call the {@link android.view.View#invalidate invalidate()}
- method to force a redraw of the screen. If you are animating View objects,
- {@link android.view.View#invalidate invalidate()} is automatically called when
- a property of the View is changed.</p>
+ <p>
+ Depending on what property or object you are animating, you might need to call
+ {@link android.view.View#invalidate invalidate()} on a View to force that area of the
+ screen to redraw itself with the new animated values. For example, animating the
+ color property of a Drawable object only cause updates to the screen when that object
+ redraws itself. All of the property setters on View,
+ such as {@link android.view.View#setAlpha setAlpha()} and
+ {@link android.view.View#setTranslationX setTranslationX()} invalidate the View
+ properly, so you do not need to invalidate the View when calling these methods with new values.
+ </p>
+
</li>
</ul>
-
- <p>You can extend the {@link android.animation.AnimatorListenerAdapter} class
- instead of implementing the {@link android.animation.Animator.AnimatorListener}
- interface, if you do not want to implement all of the methods of the {@link
- android.animation.Animator.AnimatorListener} interface. The {@link
- android.animation.AnimatorListenerAdapter} class provides empty implementations of the
- methods that you can choose to override.</p>
</li>
</ul>
+<p>You can extend the {@link android.animation.AnimatorListenerAdapter} class instead of
+implementing the {@link android.animation.Animator.AnimatorListener} interface, if you do not
+want to implement all of the methods of the {@link android.animation.Animator.AnimatorListener}
+interface. The {@link android.animation.AnimatorListenerAdapter} class provides empty
+implementations of the methods that you can choose to override.</p>
<p>For example, the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
- Bouncing Balls</a> sample in the API demos creates an {@link
- android.animation.AnimatorListenerAdapter} for just the {@link
- android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
+ Balls</a> sample in the API demos creates an {@link android.animation.AnimatorListenerAdapter}
+ for just the {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}
callback:</p>
-
- <pre>ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+ <pre>
+ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
balls.remove(((ObjectAnimator)animation).getTarget());
-}</pre>
+}
+</pre>
- <h3 id="object-animator">Animating with ObjectAnimator</h3>
- <p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link
- android.animation.ValueAnimator} (discussed in the previous section)
- and combines the timing engine and value computation
- of {@link android.animation.ValueAnimator} with the ability to animate a named property
- of a target object. This makes animating any object much easier, as you no longer need
- to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener}, because
- the animated property updates automatically.</p>
+ <h2 id="layout">Animating Layout Changes to ViewGroups</h2>
- <p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link
- android.animation.ValueAnimator}, but you also specify the object and that object's
- property (as a String) that you want to animate:</p>
- <pre>ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
-anim.setDuration(1000);
-anim.start();</pre>
+ <p>The property animation system provides the capability to animate changes to ViewGroup objects
+ as well as provide an easy way to animate View objects themselves.</p>
- <p>To have the {@link android.animation.ObjectAnimator} update properties correctly,
- you must do the following:</p>
+ <p>You can animate layout changes within a ViewGroup with the {@link
+ android.animation.LayoutTransition} class. Views inside a ViewGroup can go through an appearing
+ and disappearing animation when you add them to or remove them from a ViewGroup or when you call
+ a View's {@link android.view.View#setVisibility setVisibility()} method with {@link
+ android.view.View#VISIBLE}, android.view.View#INVISIBLE}, or {@link android.view.View#GONE}. The remaining Views in the
+ ViewGroup can also animate into their new positions when you add or remove Views. You can define
+ the following animations in a {@link android.animation.LayoutTransition} object by calling {@link
+ android.animation.LayoutTransition#setAnimator setAnimator()} and passing in an {@link
+ android.animation.Animator} object with one of the following {@link
+ android.animation.LayoutTransition} constants:</p>
<ul>
- <li>The object property that you are animating must have a setter function in the
- form of <code>set<propertyName>()</code>. Because the {@link
- android.animation.ObjectAnimator} automatically updates the property during
- animation, it must be able to access the property with this setter method. For
- example, if the property name is <code>foo</code>, you need to have a
- <code>setFoo()</code> method. If this setter method does not exist, you have three
- options:
+ <li><code>APPEARING</code> - A flag indicating the animation that runs on items that are
+ appearing in the container.</li>
- <ul>
- <li>Add the setter method to the class if you have the rights to do so.</li>
+ <li><code>CHANGE_APPEARING</code> - A flag indicating the animation that runs on items that are
+ changing due to a new item appearing in the container.</li>
- <li>Use a wrapper class that you have rights to change and have that wrapper
- receive the value with a valid setter method and forward it to the original
- object.</li>
+ <li><code>DISAPPEARING</code> - A flag indicating the animation that runs on items that are
+ disappearing from the container.</li>
- <li>Use {@link android.animation.ValueAnimator} instead.</li>
- </ul>
- </li>
-
- <li>If you specify only one value for the <code>values...</code> parameter,
- in one of the {@link android.animation.ObjectAnimator} factory methods, it is assumed to be
- the ending value of the animation. Therefore, the object property that you are
- animating must have a getter function that is used to obtain the starting value of
- the animation. The getter function must be in the form of
- <code>get<propertyName>()</code>. For example, if the property name is
- <code>foo</code>, you need to have a <code>getFoo()</code> method.</li>
-
- <li>The getter (if needed) and setter methods of the property that you are animating must
- return the same type as the starting and ending values that you specify to {@link
- android.animation.ObjectAnimator}. For example, you must have
- <code>targetObject.setPropName(float)</code> and
- <code>targetObject.getPropName(float)</code> if you construct the following {@link
- android.animation.ObjectAnimator}:
- <pre>ObjectAnimator.ofFloat(targetObject, "propName", 1f)</pre>
- </li>
+ <li><code>CHANGE_DISAPPEARING</code> - A flag indicating the animation that runs on items that
+ are changing due to an item disappearing from the container.</li>
</ul>
- <h3 id="type-evaluator">Using a TypeEvaluator</h3>
+ <p>You can define your own custom animations for these four types of events to customize the look
+ of your layout transitions or just tell the animation system to use the default animations.</p>
- <p>If you want to animate a type that is unknown to the Android system,
- you can create your own evaluator by implementing the {@link
- android.animation.TypeEvaluator} interface. The types that are known by the Android
- system are <code>int</code>, <code>float</code>, or a color, which are supported by the
- {@link android.animation.IntEvaluator}, {@link android.animation.FloatEvaluator}, and
- {@link android.animation.ArgbEvaluator} type evaluators.</p>
+ <p>The <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.html">
+ LayoutAnimations</a> sample in API Demos shows you how to define animations for layout
+ transitions and then set the animations on the View objects that you want to animate.</p>
+
+ <p>The <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.html">
+ LayoutAnimationsByDefault</a> and its corresponding <a href=
+ "{@docRoot}resources/samples/ApiDemos/res/layout/layout_animations_by_default.html">layout_animations_by_default.xml</a>
+ layout resource file show you how to enable the default layout transitions for ViewGroups in XML.
+ The only thing that you need to do is to set the <code>android:animateLayoutchanges</code>
+ attribute to <code>true</code> for the ViewGroup. For example:</p>
+ <pre>
+<LinearLayout
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:id="@+id/verticalContainer"
+ android:animateLayoutChanges="true" />
+</pre>
+
+ <p>Setting this attribute to true automatically animates Views that are added or removed from the
+ ViewGroup as well as the remaining Views in the ViewGroup.</p>
+
+ <h2 id="type-evaluator">Using a TypeEvaluator</h2>
+
+ <p>If you want to animate a type that is unknown to the Android system, you can create your own
+ evaluator by implementing the {@link android.animation.TypeEvaluator} interface. The types that
+ are known by the Android system are <code>int</code>, <code>float</code>, or a color, which are
+ supported by the {@link android.animation.IntEvaluator}, {@link
+ android.animation.FloatEvaluator}, and {@link android.animation.ArgbEvaluator} type
+ evaluators.</p>
<p>There is only one method to implement in the {@link android.animation.TypeEvaluator}
- interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method.
- This allows the animator that you are using to return an
- appropriate value for your animated property at the current point of the animation. The
- {@link android.animation.FloatEvaluator} class demonstrates how to do this:</p>
- <pre>public class FloatEvaluator implements TypeEvaluator {
+ interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method. This allows
+ the animator that you are using to return an appropriate value for your animated property at the
+ current point of the animation. The {@link android.animation.FloatEvaluator} class demonstrates
+ how to do this:</p>
+ <pre>
+public class FloatEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
}
-}</pre>
+}
+</pre>
- <p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or
- {@link android.animation.ObjectAnimator}) runs, it calculates a current elapsed
- fraction of the animation (a value between 0 and 1) and then calculates an eased
- version of that depending on what interpolator that you are using. The eased fraction
- is what your {@link android.animation.TypeEvaluator} receives through the <code>fraction</code>
- parameter, so you do not have to take into account the interpolator
- when calculating animated values.</p>
+ <p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or {@link
+ android.animation.ObjectAnimator}) runs, it calculates a current elapsed fraction of the
+ animation (a value between 0 and 1) and then calculates an interpolated version of that depending
+ on what interpolator that you are using. The interpolated fraction is what your {@link
+ android.animation.TypeEvaluator} receives through the <code>fraction</code> parameter, so you do
+ not have to take into account the interpolator when calculating animated values.</p>
- <h3 id="interpolators">Using interpolators</h3>
+ <h2 id="interpolators">Using Interpolators</h2>
- <p>An interpolator define how specific values in an animation are
- calculated as a function of time. For example, you can specify animations to happen
- linearly across the whole animation, meaning the animation moves evenly the entire
- time, or you can specify animations to use non-linear time, for example, using
- acceleration or deceleration at the beginning or end of the animation.</p>
-
- <p>Interpolators in the animation system receive a fraction from Animators that represent the elapsed time
- of the animation. Interpolators modify this fraction to coincide with the type of
- animation that it aims to provide. The Android system provides a set of common
- interpolators in the {@link android.view.animation android.view.animation package}. If
- none of these suit your needs, you can implement the {@link
- android.animation.TimeInterpolator} interface and create your own.</p>
+ <p>An interpolator define how specific values in an animation are calculated as a function of
+ time. For example, you can specify animations to happen linearly across the whole animation,
+ meaning the animation moves evenly the entire time, or you can specify animations to use
+ non-linear time, for example, using acceleration or deceleration at the beginning or end of the
+ animation.</p>
+
+ <p>Interpolators in the animation system receive a fraction from Animators that represent the
+ elapsed time of the animation. Interpolators modify this fraction to coincide with the type of
+ animation that it aims to provide. The Android system provides a set of common interpolators in
+ the {@link android.view.animation android.view.animation package}. If none of these suit your
+ needs, you can implement the {@link android.animation.TimeInterpolator} interface and create your
+ own.</p>
<p>As an example, how the default interpolator {@link
android.view.animation.AccelerateDecelerateInterpolator} and the {@link
- android.view.animation.LinearInterpolator} calculate eased fractions are compared below. The {@link
- android.view.animation.LinearInterpolator} has no effect on the elapsed fraction,
- because a linear interpolation is calculated the same way as the elapsed fraction. The
- {@link android.view.animation.AccelerateDecelerateInterpolator} accelerates into the
- animation and decelerates out of it. The following methods define the logic for these
- interpolators:</p>
+ android.view.animation.LinearInterpolator} calculate interpolated fractions are compared below.
+ The {@link android.view.animation.LinearInterpolator} has no effect on the elapsed fraction. The {@link
+ android.view.animation.AccelerateDecelerateInterpolator} accelerates into the animation and
+ decelerates out of it. The following methods define the logic for these interpolators:</p>
<p><strong>AccelerateDecelerateInterpolator</strong></p>
- <pre>public float getInterpolation(float input) {
+ <pre>
+public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
-}</pre>
+}
+</pre>
<p><strong>LinearInterpolator</strong></p>
- <pre>public float getInterpolation(float input) {
+ <pre>
+public float getInterpolation(float input) {
return input;
-}</pre>
+}
+</pre>
<p>The following table represents the approximate values that are calculated by these
interpolators for an animation that lasts 1000ms:</p>
@@ -423,9 +729,9 @@
<tr>
<th>ms elapsed</th>
- <th>Elapsed fraction/Eased fraction (Linear)</th>
+ <th>Elapsed fraction/Interpolated fraction (Linear)</th>
- <th>Eased fraction (Accelerate/Decelerate)</th>
+ <th>Interpolated fraction (Accelerate/Decelerate)</th>
</tr>
<tr>
@@ -477,152 +783,167 @@
</tr>
</table>
- <p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes
- the values at the same speed, .2 for every 200ms that passes. The {@link
- android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than
- {@link android.view.animation.LinearInterpolator} between 200ms and 600ms and slower
- between 600ms and 1000ms.</p>
+ <p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes the values
+ at the same speed, .2 for every 200ms that passes. The {@link
+ android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than {@link
+ android.view.animation.LinearInterpolator} between 200ms and 600ms and slower between 600ms and
+ 1000ms.</p>
- <h3 id="keyframes">Specifying keyframes</h3>
+ <h2 id="keyframes">Specifying Keyframes</h2>
- <p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets
- you define a specific state at a specific time of an animation. Each keyframe can also
- have its own interpolator to control the behavior of the animation in the interval
- between the previous keyframe's time and the time of this keyframe.</p>
+ <p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets you define
+ a specific state at a specific time of an animation. Each keyframe can also have its own
+ interpolator to control the behavior of the animation in the interval between the previous
+ keyframe's time and the time of this keyframe.</p>
- <p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the
- factory methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link
- android.animation.Keyframe#ofFloat ofFloat()}, or {@link
- android.animation.Keyframe#ofObject ofObject()} to obtain the appropriate type of
- {@link android.animation.Keyframe}. You then call the {@link
- android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to
- obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the
- object, you can obtain an animator by passing in the {@link
- android.animation.PropertyValuesHolder} object and the object to animate. The following
- code snippet demonstrates how to do this:</p>
- <pre>Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
-Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
+ <p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the factory
+ methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link
+ android.animation.Keyframe#ofFloat ofFloat()}, or {@link android.animation.Keyframe#ofObject
+ ofObject()} to obtain the appropriate type of {@link android.animation.Keyframe}. You then call
+ the {@link android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to
+ obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the object, you can
+ obtain an animator by passing in the {@link android.animation.PropertyValuesHolder} object and
+ the object to animate. The following code snippet demonstrates how to do this:</p>
+ <pre>
+Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
rotationAnim.setDuration(5000ms);
</pre>
-<p>For a more complete example on how to use keyframes, see the <a href=
-"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html">
+
+ <p>For a more complete example on how to use keyframes, see the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html">
MultiPropertyAnimation</a> sample in APIDemos.</p>
- <h3 id="choreography">Choreographing multiple animations with AnimatorSet</h3>
+ <h2 id="views">Animating Views</h2>
- <p>In many cases, you want to play an animation that depends on when another animation
- starts or finishes. The Android system lets you bundle animations together into an
- {@link android.animation.AnimatorSet}, so that you can specify whether to start animations
- simultaneously, sequentially, or after a specified delay. You can also nest {@link
- android.animation.AnimatorSet} objects within each other.</p>
+ <p>The property animation system allow streamlined animation of View objects and offerse
+ a few advantages over the view animation system. The view
+ animation system transformed View objects by changing the way that they were drawn. This was
+ handled in the container of each View, because the View itself had no properties to manipulate.
+ This resulted in the View being animated, but caused no change in the View object itself. This
+ led to behavior such as an object still existing in its original location, even though it was
+ drawn on a different location on the screen. In Android 3.0, new properties and the corresponding
+ getter and setter methods were added to eliminate this drawback.</p>
+ <p>The property animation system
+ can animate Views on the screen by changing the actual properties in the View objects. In
+ addition, Views also automatically call the {@link android.view.View#invalidate invalidate()}
+ method to refresh the screen whenever its properties are changed. The new properties in the {@link
+ android.view.View} class that facilitate property animations are:</p>
- <p>The following sample code taken from the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
- Bouncing Balls</a> sample (modified for simplicity) plays the following
- {@link android.animation.Animator} objects in the following manner:</p>
+ <ul>
+ <li><code>translationX</code> and <code>translationY</code>: These properties control where the
+ View is located as a delta from its left and top coordinates which are set by its layout
+ container.</li>
- <ol>
- <li>Plays <code>bounceAnim</code>.</li>
+ <li><code>rotation</code>, <code>rotationX</code>, and <code>rotationY</code>: These properties
+ control the rotation in 2D (<code>rotation</code> property) and 3D around the pivot point.</li>
- <li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>,
- <code>stretchAnim1</code>, and <code>stretchAnim2</code> at the same time.</li>
+ <li><code>scaleX</code> and <code>scaleY</code>: These properties control the 2D scaling of a
+ View around its pivot point.</li>
- <li>Plays <code>bounceBackAnim</code>.</li>
+ <li><code>pivotX</code> and <code>pivotY</code>: These properties control the location of the
+ pivot point, around which the rotation and scaling transforms occur. By default, the pivot
+ point is located at the center of the object.</li>
- <li>Plays <code>fadeAnim</code>.</li>
- </ol>
- <pre>AnimatorSet bouncer = new AnimatorSet();
-bouncer.play(bounceAnim).before(squashAnim1);
-bouncer.play(squashAnim1).with(squashAnim2);
-bouncer.play(squashAnim1).with(stretchAnim1);
-bouncer.play(squashAnim1).with(stretchAnim2);
-bouncer.play(bounceBackAnim).after(stretchAnim2);
-ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
-fadeAnim.setDuration(250);
-AnimatorSet animatorSet = new AnimatorSet();
-animatorSet.play(bouncer).before(fadeAnim);
-animatorSet.start();
+ <li><code>x</code> and <code>y</code>: These are simple utility properties to describe the
+ final location of the View in its container, as a sum of the left and top values and
+ translationX and translationY values.</li>
+
+ <li><code>alpha</code>: Represents the alpha transparency on the View. This value is 1 (opaque)
+ by default, with a value of 0 representing full transparency (not visible).</li>
+ </ul>
+
+ <p>To animate a property of a View object, such as its color or rotation value, all you need to
+ do is create a property animator and specify the View property that you want to
+ animate. For example:</p>
+ <pre>
+ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
</pre>
- <p>For a more complete example on how to use animator sets, see the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
- Bouncing Balls</a> sample in APIDemos.</p>
+For more information on creating animators, see the sections on animating with
+<a href="#value-animator">ValueAnimator</a> and <a href="#object-animator">ObjectAnimator</a>
- <h3 id="declaring-xml">Declaring animations in XML</h3>
+ <h2 id="declaring-xml">Declaring Animations in XML</h2>
- <p>As with <a href="#view-animation">view animation</a>, you can declare property animations with
- XML instead of doing it programmatically. The following Android classes also have XML
- declaration support with the following XML tags:</p>
+ <p>The property animation system lets you declare property animations with XML instead of doing
+ it programmatically. The following Android classes have XML declaration support with the
+ following XML tags:</p>
<ul>
<li>{@link android.animation.ValueAnimator} - <code><animator></code></li>
<li>{@link android.animation.ObjectAnimator} - <code><objectAnimator></code></li>
- <li>{@link android.animation.AnimatorSet} - <code><AnimatorSet></code></li>
+ <li>{@link android.animation.AnimatorSet} - <code><set></code></li>
</ul>
<p>Both <code><animator></code> ({@link android.animation.ValueAnimator}) and
- <code><objectAnimator></code> ({@link android.animation.ObjectAnimator}) have the
- following attributes:</p>
+ <code><objectAnimator></code> ({@link android.animation.ObjectAnimator}) have the following
+ attributes:</p>
- <dl>
- <dt><code>android:duration</code></dt>
- <dd>The number of milliseconds that the animation runs.</dd>
-
- <dt><code>android:valueFrom</code> and <code>android:valueTo</code></dt>
- <dd>The values being animated
- between. These are restricted to numbers (<code>float</code> or <code>int</code>) in
- XML. They can be <code>float</code>, <code>int</code>, or any kind of
- <code>Object</code> when creating animations programmatically.</dd>
-
- <dt><code>android:valueType</code></dt>
- <dd>Set to either <code>"floatType"</code> or <code>"intType"</code>.</dd>
-
- <dt><code>android:startDelay</code></dt>
- <dd>The delay, in milliseconds, before the animation begins
- playing (after calling {@link android.animation.ValueAnimator#start start()}).</dd>
-
- <dt><code>android:repeatCount</code></dt>
- <dd>How many times to repeat an animation. Set to
- <code>"-1"</code> for infinite repeating or to a positive integer. For example, a value of
- <code>"1"</code> means that the animation is repeated once after the initial run of the
- animation, so the animation plays a total of two times. The default value is
- <code>"0"</code>.</dd>
+ <dl>
+ <dt><code>android:duration</code></dt>
- <dt><code>android:repeatMode</code></dt>
- <dd>How an animation behaves when it reaches the end of the
- animation. <code>android:repeatCount</code> must be set to a positive integer or
- <code>"-1"</code> for this attribute to have an effect. Set to <code>"reverse"</code> to
- have the animation reverse direction with each iteration or <code>"repeat"</code> to
- have the animation loop from the beginning each time.</dd>
+ <dd>The number of milliseconds that the animation runs. The default is 300 ms.</dd>
+
+ <dt><code>android:valueFrom</code> and <code>android:valueTo</code></dt>
+
+ <dd>The values being animated between. These are restricted to numbers (<code>float</code> or
+ <code>int</code>) and color values (such as #00ff00). They can be <code>float</code>, <code>int</code>, colors,
+ or any kind of <code>Object</code> when creating animations programmatically.</dd>
+
+ <dt><code>android:valueType</code></dt>
+
+ <dd>Set to either <code>"floatType"</code> or <code>"intType"</code>. The default is
+ <code>"floatType"</code> unless you specify something else or if the <code>valuesFrom</code>
+ and <code>valuesTo</code> values are colors.</dd>
+
+ <dt><code>android:startDelay</code></dt>
+
+ <dd>The delay, in milliseconds, before the animation begins playing (after calling {@link
+ android.animation.ValueAnimator#start start()}).</dd>
+
+ <dt><code>android:repeatCount</code></dt>
+
+ <dd>How many times to repeat an animation. Set to <code>"-1"</code> to infinitely repeat or
+ to a positive integer. For example, a value of <code>"1"</code> means that the animation is
+ repeated once after the initial run of the animation, so the animation plays a total of two
+ times. The default value is <code>"0"</code>, which means no repetition.</dd>
+
+ <dt><code>android:repeatMode</code></dt>
+
+ <dd>How an animation behaves when it reaches the end of the animation.
+ <code>android:repeatCount</code> must be set to a positive integer or <code>"-1"</code> for
+ this attribute to have an effect. Set to <code>"reverse"</code> to have the animation reverse
+ direction with each iteration or <code>"repeat"</code> to have the animation loop from the
+ beginning each time.</dd>
</dl>
-
+
<p>The <code>objectAnimator</code> ({@link android.animation.ObjectAnimator}) element has the
- additional attribute <code>propertyName</code>, that lets you specify the name of the
- property being animated. The <code>objectAnimator</code> element does not expose a
- <code>target</code> attribute, however, so you cannot set the object to animate in the
- XML declaration. You have to inflate the XML resource by calling
- {@link android.animation.AnimatorInflater#loadAnimator loadAnimator()} and call
- {@link android.animation.ObjectAnimator#setTarget setTarget()} to set the target object, before calling
- {@link android.animation.ObjectAnimator#start start()}.</p>
+ additional attribute <code>propertyName</code>, that lets you specify the name of the property
+ being animated. The <code>objectAnimator</code> element does not expose a <code>target</code>
+ attribute, however, so you cannot set the object to animate in the XML declaration. You have to
+ inflate the XML resource by calling {@link android.animation.AnimatorInflater#loadAnimator
+ loadAnimator()} and call {@link android.animation.ObjectAnimator#setTarget setTarget()} to set
+ the target object unlike the underlying {@link android.animation.ObjectAnimator},
+ before calling {@link android.animation.ObjectAnimator#start start()}.</p>
<p>The <code>set</code> element ({@link android.animation.AnimatorSet}) exposes a single
- attribute, <code>ordering</code>. Set this attribute to <code>together</code> (default)
- to play all the animations in this set at once. Set this attribute to
- <code>sequentially</code> to play the animations in the order they are declared.</p>
+ attribute, <code>ordering</code>. Set this attribute to <code>together</code> (default) to play
+ all the animations in this set at once. Set this attribute to <code>sequentially</code> to play
+ the animations in the order they are declared.</p>
- <p>You can specify nested <code>set</code> tags to further group animations together.
- The animations that you want to group together should be children of the
- <code>set</code> tag and can define their own <code>ordering</code> attribute.</p>
+ <p>You can specify nested <code>set</code> tags to further group animations together. The
+ animations that you want to group together should be children of the <code>set</code> tag and can
+ define their own <code>ordering</code> attribute.</p>
- <p>As an example, this XML code creates an {@link android.animation.AnimatorSet} object
- that animates x and y at the same time (<code>together</code> is the default ordering
- when nothing is specified), then runs an animation that fades an object out:</p>
- <pre><set android:ordering="sequentially">
+ <p>As an example, this XML code creates an {@link android.animation.AnimatorSet} object that
+ animates x and y at the same time, then runs an animation that fades an object out:</p>
+ <pre>
+<set android:ordering="sequentially">
<set>
<objectAnimator
android:propertyName="x"
@@ -639,190 +960,11 @@
android:propertyName="alpha"
android:duration="500"
android:valueTo="0f"/>
-</set></pre>
-
- <p>In order to run this animation, you must inflate the XML resources in your code to
- an {@link android.animation.AnimatorSet} object, and then set the target objects for all of
- the animations before starting the animation set. Calling {@link
- android.animation.AnimatorSet#setTarget setTarget()} sets a single target object for
- all children of the {@link android.animation.AnimatorSet}.</p>
-
- <h2 id="view-animation">View Animation</h2>You can use View Animation in any View
- object to perform tweened animation and frame by frame animation. Tween animation
- calculates the animation given information such as the start point, end point, size,
- rotation, and other common aspects of an animation. Frame by frame animation lets you
- load a series of Drawable resources one after another to create an animation.
-
- <h3 id="tween-animation">Tween Animation</h3>
-
- <p>A tween animation can perform a series of simple transformations (position, size,
- rotation, and transparency) on the contents of a View object. So, if you have a
- {@link android.widget.TextView} object, you can move, rotate, grow, or shrink the text. If it has a background
- image, the background image will be transformed along with the text. The {@link
- android.view.animation animation package} provides all the classes used in a tween
- animation.</p>
-
- <p>A sequence of animation instructions defines the tween animation, defined by either
- XML or Android code. As with defining a layout, an XML file is recommended because it's
- more readable, reusable, and swappable than hard-coding the animation. In the example
- below, we use XML. (To learn more about defining an animation in your application code,
- instead of XML, refer to the {@link android.view.animation.AnimationSet} class and
- other {@link android.view.animation.Animation} subclasses.)</p>
-
- <p>The animation instructions define the transformations that you want to occur, when
- they will occur, and how long they should take to apply. Transformations can be
- sequential or simultaneous — for example, you can have the contents of a TextView
- move from left to right, and then rotate 180 degrees, or you can have the text move and
- rotate simultaneously. Each transformation takes a set of parameters specific for that
- transformation (starting size and ending size for size change, starting angle and
- ending angle for rotation, and so on), and also a set of common parameters (for
- instance, start time and duration). To make several transformations happen
- simultaneously, give them the same start time; to make them sequential, calculate the
- start time plus the duration of the preceding transformation.</p>
-
- <p>The animation XML file belongs in the <code>res/anim/</code> directory of your
- Android project. The file must have a single root element: this will be either a single
- <code><alpha></code>, <code><scale></code>, <code><translate></code>,
- <code><rotate></code>, interpolator element, or <code><set></code> element
- that holds groups of these elements (which may include another
- <code><set></code>). By default, all animation instructions are applied
- simultaneously. To make them occur sequentially, you must specify the
- <code>startOffset</code> attribute, as shown in the example below.</p>
-
- <p>The following XML from one of the ApiDemos is used to stretch, then simultaneously
- spin and rotate a View object.</p>
- <pre><set android:shareInterpolator="false">
- <scale
- android:interpolator="@android:anim/accelerate_decelerate_interpolator"
- android:fromXScale="1.0"
- android:toXScale="1.4"
- android:fromYScale="1.0"
- android:toYScale="0.6"
- android:pivotX="50%"
- android:pivotY="50%"
- android:fillAfter="false"
- android:duration="700" />
- <set android:interpolator="@android:anim/decelerate_interpolator">
- <scale
- android:fromXScale="1.4"
- android:toXScale="0.0"
- android:fromYScale="0.6"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="700"
- android:duration="400"
- android:fillBefore="false" />
- <rotate
- android:fromDegrees="0"
- android:toDegrees="-45"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="700"
- android:duration="400" />
- </set>
-</set></pre>
-
- <p>Screen coordinates (not used in this example) are (0,0) at the upper left hand
- corner, and increase as you go down and to the right.</p>
-
- <p>Some values, such as pivotX, can be specified relative to the object itself or
- relative to the parent. Be sure to use the proper format for what you want ("50" for
- 50% relative to the parent, or "50%" for 50% relative to itself).</p>
-
- <p>You can determine how a transformation is applied over time by assigning an {@link
- android.view.animation.Interpolator}. Android includes several Interpolator subclasses
- that specify various speed curves: for instance, {@link
- android.view.animation.AccelerateInterpolator} tells a transformation to start slow and
- speed up. Each one has an attribute value that can be applied in the XML.</p>
-
- <p>With this XML saved as <code>hyperspace_jump.xml</code> in the
- <code>res/anim/</code> directory of the project, the following code will reference
- it and apply it to an {@link android.widget.ImageView} object from the layout.</p>
- <pre>
-ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
-Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
-spaceshipImage.startAnimation(hyperspaceJumpAnimation);
+</set>
</pre>
- <p>As an alternative to <code>startAnimation()</code>, you can define a starting time
- for the animation with <code>{@link android.view.animation.Animation#setStartTime(long)
- Animation.setStartTime()}</code>, then assign the animation to the View with
- <code>{@link android.view.View#setAnimation(android.view.animation.Animation)
- View.setAnimation()}</code>.</p>
-
- <p>For more information on the XML syntax, available tags and attributes, see <a href=
- "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
-
- <p class="note"><strong>Note:</strong> Regardless of how your animation may move or
- resize, the bounds of the View that holds your animation will not automatically adjust
- to accommodate it. Even so, the animation will still be drawn beyond the bounds of its
- View and will not be clipped. However, clipping <em>will occur</em> if the animation
- exceeds the bounds of the parent View.</p>
-
- <h3 id="frame-animation">Frame Animation</h3>
-
- <p>This is a traditional animation in the sense that it is created with a sequence of
- different images, played in order, like a roll of film. The {@link
- android.graphics.drawable.AnimationDrawable} class is the basis for frame
- animations.</p>
-
- <p>While you can define the frames of an animation in your code, using the {@link
- android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished
- with a single XML file that lists the frames that compose the animation. Like the tween
- animation above, the XML file for this kind of animation belongs in the
- <code>res/drawable/</code> directory of your Android project. In this case, the
- instructions are the order and duration for each frame of the animation.</p>
-
- <p>The XML file consists of an <code><animation-list></code> element as the root
- node and a series of child <code><item></code> nodes that each define a frame: a
- drawable resource for the frame and the frame duration. Here's an example XML file for
- a frame-by-frame animation:</p>
- <pre>
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="true">
- <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
- <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
- <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
-</animation-list>
-</pre>
-
- <p>This animation runs for just three frames. By setting the
- <code>android:oneshot</code> attribute of the list to <var>true</var>, it will cycle
- just once then stop and hold on the last frame. If it is set <var>false</var> then the
- animation will loop. With this XML saved as <code>rocket_thrust.xml</code> in the
- <code>res/drawable/</code> directory of the project, it can be added as the background
- image to a View and then called to play. Here's an example Activity, in which the
- animation is added to an {@link android.widget.ImageView} and then animated when the
- screen is touched:</p>
- <pre>AnimationDrawable rocketAnimation;
-
-public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
- rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
- rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
-}
-
-public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- rocketAnimation.start();
- return true;
- }
- return super.onTouchEvent(event);
-}</pre>
-
- <p>It's important to note that the <code>start()</code> method called on the
- AnimationDrawable cannot be called during the <code>onCreate()</code> method of your
- Activity, because the AnimationDrawable is not yet fully attached to the window. If you
- want to play the animation immediately, without requiring interaction, then you might
- want to call it from the <code>{@link
- android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code>
- method in your Activity, which will get called when Android brings your window into
- focus.</p>
-
- <p>For more information on the XML syntax, available tags and attributes, see <a href=
- "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
\ No newline at end of file
+ <p>In order to run this animation, you must inflate the XML resources in your code to an {@link
+ android.animation.AnimatorSet} object, and then set the target objects for all of the animations
+ before starting the animation set. Calling {@link android.animation.AnimatorSet#setTarget
+ setTarget()} sets a single target object for all children of the {@link
+ android.animation.AnimatorSet}.</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/graphics/renderscript.jd b/docs/html/guide/topics/graphics/renderscript.jd
new file mode 100644
index 0000000..0ef8a22
--- /dev/null
+++ b/docs/html/guide/topics/graphics/renderscript.jd
@@ -0,0 +1,710 @@
+page.title=3D Rendering and Computation with Renderscript
+@jd:body
+
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li><a href="#overview">Renderscript System Overview</a></li>
+
+ <li>
+ <a href="#api">API Overview</a>
+
+ <ol>
+ <li><a href="#native-api">Native Renderscript APIs</a></li>
+
+ <li><a href="#reflective-api">Reflective layer APIs</a></li>
+
+ <li><a href="#graphics-api">Graphics APIs</a></li>
+ </ol>
+ </li>
+
+ <li>
+ <a href="#developing">Developing a Renderscript application</a>
+
+ <ol>
+ <li><a href="#hello-graphics">The Hello Graphics application</a></li>
+ </ol>
+ </li>
+ </ol>
+ </div>
+ </div>
+
+ <p>The Renderscript system offers high performance 3D rendering and mathematical computations at
+ the native level. The Renderscript APIs are intended for developers who are comfortable with
+ developing in C (C99 standard) and want to maximize performance in their applications. The
+ Renderscript system improves performance by running as native code on the device, but it also
+ features cross-platform functionality. To achieve this, the Android build tools compile your
+ Renderscript <code>.rs</code> file to intermediate bytecode and package it inside your
+ application's <code>.apk</code> file. On the device, the bytecode is compiled (just-in-time) to
+ machine code that is further optimized for the device that it is running on. This eliminates the
+ need to target a specific architecture during the development process. The compiled code on the
+ device is cached, so subsequent uses of the Renderscript enabled application do not recompile the
+ intermediate code.</p>
+
+ <p>The disadvantage of the Renderscript system is that it adds complexity to the development and
+ debugging processes and is not a substitute for the Android system APIs. It is a portable native
+ language with pointers and explicit resource management. The target use is for performance
+ critical code where the existing Android APIs are not sufficient. If what you are rendering or
+ computing is very simple and does not require much processing power, you should still use the
+ Android APIs for ease of development. Debugging visibility can be limited, because the
+ Renderscript system can execute on processors other than the main CPU (such as the GPU), so if
+ this occurs, debugging becomes more difficult. Remember the tradeoffs between development and
+ debugging complexity versus performance when deciding to use Renderscript.</p>
+
+ <p>For an example of Renderscript in action, see the 3D carousel view in the Android 3.0 versions
+ of Google Books and YouTube or install the Renderscript sample applications that are shipped with
+ the SDK in <code><sdk_root>/platforms/android-3.0/samples</code>.</p>
+
+ <h2 id="overview">Renderscript System Overview</h2>
+
+ <p>The Renderscript system adopts a control and slave architecture where the low-level native
+ code is controlled by the higher level Android system that runs in the virtual machine (VM). When
+ you use the Renderscript system, there are three layers of APIs that exist:</p>
+
+ <ul>
+ <li>The native Renderscript layer consists of the native Renderscript <code>.rs</code> files
+ that you write to compute mathematical operations, render graphics, or both. This layer does
+ the intensive computation or graphics rendering and returns the result back to the Android VM
+ through the reflected layer.</li>
+
+ <li>The reflected layer is a set of generated Android system classes (through reflection) based
+ on the native layer interface that you define. This layer acts as a bridge between the native
+ Renderscript layer and the Android system layer. The Android build tools automatically generate
+ the APIs for this layer during the build process.</li>
+
+ <li>The Android system layer consists of your normal Android APIs along with the Renderscript
+ APIs in {@link android.renderscript}. This layer handles things such as the Activity lifecycle
+ management of your application and calls the native Renderscript layer through the reflected
+ layer.</li>
+ </ul>
+
+ <p>To fully understand how the Renderscript system works, you must understand how the reflected
+ layer is generated and how it interacts with the native Renderscript layer and Android system
+ layer. The reflected layer provides the entry points into the native code, enabling the Android
+ system code to give high level commands like, "rotate the view" or "filter the bitmap." It
+ delegates all the heavy lifting to the native layer. To accomplish this, you need to create logic
+ to hook together all of these layers so that they can correctly communicate.</p>
+
+ <p>At the root of everything is your Renderscript, which is the actual C code that you write and
+ save to a <code>.rs</code> file in your project. There are two kinds of Renderscripts: compute
+ and graphics. A compute Renderscript does not do any graphics rendering while a graphics
+ Renderscript does.</p>
+
+ <p>When you create a Renderscript <code>.rs</code> file, an equivalent, reflective layer class,
+ {@link android.renderscript.ScriptC}, is generated by the build tools and exposes the native
+ functions to the Android system. This class is named
+ <code><em>ScriptC_renderscript_filename</em></code>. The following list describes the major
+ components of your native Renderscript code that is reflected:</p>
+
+ <ul>
+ <li>The non-static functions in your Renderscript (<code>.rs</code> file) are reflected into
+ <code><em>ScriptC_renderscript_filename</em></code> of type {@link
+ android.renderscript.ScriptC}.</li>
+
+ <li>Any non-static, global Renderscript variables are reflected into
+ <code><em>ScriptC_renderscript_filename</em></code>.
+ Accessor methods are generated, so the Android system layer can access the values.
+ The <code>get()</code> method comes with a one-way communication restriction.
+ The Android system layer always caches the last value that is set and returns that during a call to get.
+ If the native Renderscript code has changed the value, the change does propagate back to the Android system layer
+ for efficiency. If the global variables are initialized in the native Renderscript code, those values are used
+ to initialize the Android system versions. If global variables are marked as <code>const</code>,
+ then a <code>set()</code> method is not generated.
+ </li>
+
+ <li>Structs are reflected into their own classes, one for each struct, into a class named
+ <code>ScriptField_<em>struct_name</em></code> of type {@link
+ android.renderscript.Script.FieldBase}.</li>
+
+ <li>Global pointers have a special property. They provide attachment points where the Android system can attach allocations.
+ If the global pointer is a user defined structure type, it must be a type that is legal for reflection (primitives
+ or Renderscript data types). The Android system can call the reflected class to allocate memory and
+ optionally populate data, then attach it to the Renderscript.
+ For arrays of basic types, the procedure is similar, except a reflected class is not needed.
+ Renderscripts should not directly set the exported global pointers.</li>
+ </ul>
+
+ <p>The Android system also has a corresponding Renderscript context object, {@link
+ android.renderscript.RenderScript} (for a compute Renderscript) or {@link
+ android.renderscript.RenderScriptGL} (for a graphics Renderscript). This context object allows
+ you to bind to the reflected Renderscript class, so that the Renderscript context knows what its
+ corresponding native Renderscript is. If you have a graphics Renderscript context, you can also
+ specify a variety of Programs (stages in the graphics pipeline) to tweek how your graphics are
+ rendered. A graphics Renderscript context also needs a surface to render on, {@link
+ android.renderscript.RSSurfaceView}, which gets passed into its constructor. When all three of
+ the layers are connected, the Renderscript system can compute or render graphics.</p>
+
+ <h2 id="api">API overview</h2>
+
+ <p>Renderscript code is compiled and executed in a compact and well defined runtime, which has
+ access to a limited amount of functions. Renderscript cannot use the NDK or standard C functions,
+ because these functions are assumed to be running on a standard CPU. The Renderscript runtime
+ chooses the best processor to execute the code, which may not be the CPU, so it cannot guarantee
+ support for standard C libraries. What Renderscript does offer is an API that supports intensive
+ computation with an extensive collection of math APIs. Some key features of the Renderscript APIs
+ are:</p>
+
+
+ <h3 id="native-api">Native Renderscript APIs</h3>
+
+ <p>The Renderscript headers are located in the <code>include</code> and
+ <code>clang-include</code> directories in the
+ <code><sdk_root>/platforms/android-3.0/renderscript</code> directory of the Android SDK.
+ The headers are automatically included for you, except for the graphics specific header,
+ which you can define as follows:</p>
+
+<pre>#include "rs_graphics.rsh"</pre>
+
+<p>Some key features of the native Renderscript libraries include:
+ <ul>
+ <li>A large collection of math functions with both scalar and vector typed overloaded versions
+ of many common routines. Operations such as adding, multiplying, dot product, and cross product
+ are available.</li>
+ <li>Conversion routines for primitive data types and vectors, matrix routines, date and time
+ routines, and graphics routines.</li>
+ <li>Logging functions</li>
+ <li>Graphics rendering functions</li>
+ <li>Memory allocation request features</li>
+ <li>Data types and structures to support the Renderscript system such as
+ Vector types for defining two-, three-, or four-vectors.</li></li>
+ </ul>
+ </ul>
+
+ <h3 id="reflective-api">Reflective layer APIs</h3>
+
+ <p>These classes are not generated by the reflection process, and are actually part of the
+ Android system APIs, but they are mainly used by the reflective layer classes to handle memory
+ allocation and management for your Renderscript. You normally do not need to be call these classes
+ directly.</p>
+
+ <p>Because of the constraints of the Renderscript native layer, you cannot do any dynamic
+ memory allocation in your Renderscript <code>.rs</code> file.
+ The native Renderscript layer can request memory from the Android system layer, which allocates memory
+ for you and does reference counting to figure out when to free the memory. A memory allocation
+ is taken care of by the {@link android.renderscript.Allocation} class and memory is requested
+ in your Renderscript code with the <code>the rs_allocation</code> type.
+ All references to Renderscript objects are counted, so when your Renderscript native code
+ or system code no longer references a particular {@link android.renderscript.Allocation}, it destroys itself.
+ Alternatively, you can call {@link android.renderscript.Allocation#destroy destroy()} from the
+ Android system level, which decreases the reference to the {@link android.renderscript.Allocation}.
+ If no references exist after the decrease, the {@link android.renderscript.Allocation} destroys itself.
+ The Android system object, which at this point is just an empty shell, is eventually garbage collected.
+ </p>
+
+ <p>The following classes are mainly used by the reflective layer classes:</p>
+
+ <table>
+ <tr>
+ <th>Android Object Type</th>
+
+ <th>Renderscript Native Type</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.Element}</td>
+
+ <td>rs_element</td>
+
+ <td>
+ An {@link android.renderscript.Element} is the most basic element of a memory type. An
+ element represents one cell of a memory allocation. An element can have two forms: Basic or
+ Complex. They are typically created from C structures that are used within Renderscript
+ code and cannot contain pointers or nested arrays. The other common source of elements is
+ bitmap formats.
+
+ <p>A basic element contains a single component of data of any valid Renderscript data type.
+ Examples of basic element data types include a single float value, a float4 vector, or a
+ single RGB-565 color.</p>
+
+ <p>Complex elements contain a list of sub-elements and names that is basically a reflection
+ of a C struct. You access the sub-elements by name from a script or vertex program. The
+ most basic primitive type determines the data alignment of the structure. For example, a
+ float4 vector is alligned to <code>sizeof(float)</code> and not
+ <code>sizeof(float4)</code>. The ordering of the elements in memory are the order in which
+ they were added, with each component aligned as necessary.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.Type}</td>
+
+ <td>rs_type</td>
+
+ <td>A Type is an allocation template that consists of an element and one or more dimensions.
+ It describes the layout of the memory but does not allocate storage for the data that it
+ describes. A Type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of
+ a cube map). You can assign the X,Y,Z dimensions to any positive integer value within the
+ constraints of available memory. A single dimension allocation has an X dimension of greater
+ than zero while the Y and Z dimensions are zero to indicate not present. For example, an
+ allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is considered one
+ dimensional. The LOD and Faces dimensions are booleans to indicate present or not
+ present.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.Allocation}</td>
+
+ <td>rs_allocation</td>
+
+ <td>
+ An {@link android.renderscript.Allocation} provides the memory for applications. An {@link
+ android.renderscript.Allocation} allocates memory based on a description of the memory that
+ is represented by a {@link android.renderscript.Type}. The {@link
+ android.renderscript.Type} describes an array of {@link android.renderscript.Element}s that
+ represent the memory to be allocated. Allocations are the primary way data moves into and
+ out of scripts.
+
+ <p>Memory is user-synchronized and it's possible for allocations to exist in multiple
+ memory spaces concurrently. For example, if you make a call to the graphics card to load a
+ bitmap, you give it the bitmap to load from in the system memory. After that call returns,
+ the graphics memory contains its own copy of the bitmap so you can choose whether or not to
+ maintain the bitmap in the system memory. If the Renderscript system modifies an allocation
+ that is used by other targets, it must call {@link android.renderscript#syncAll syncAll()} to push the updates to
+ the memory. Otherwise, the results are undefined.</p>
+
+ <p>Allocation data is uploaded in one of two primary ways: type checked and type unchecked.
+ For simple arrays there are <code>copyFrom()</code> functions that take an array from the
+ Android system code and copy it to the native layer memory store. Both type checked and
+ unchecked copies are provided. The unchecked variants allow the Android system to copy over
+ arrays of structures because it not support inherently support structures. For example, if
+ there is an allocation that is an array n floats, you can copy the data contained in a
+ float[n] array or a byte[n*4] array.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.Script}</td>
+
+ <td>rs_script</td>
+
+ <td>Renderscript scripts do much of the work in the native layer. This class is generated
+ from a Renderscript file that has the <code>.rs</code> file extension. This class is named
+ <code>ScriptC_<em>rendersript_filename</em></code> when it gets generated.</td>
+ </tr>
+ </table>
+
+ <h3 id="graphics-api">Graphics API</h3>
+
+ <p>Renderscript provides a number of graphics APIs for hardware-accelerated 3D rendering. The
+ Renderscript graphics APIs include a stateful context, {@link
+ android.renderscript.RenderScriptGL} that contains the current rendering state. The primary state
+ consists of the objects that are attached to the rendering context, which are the graphics Renderscript
+ and the four program types. The main working function of the graphics Renderscript is the code that is
+ defined in the <code>root()</code> function. The <code>root()</code> function is called each time the surface goes through a frame
+ refresh. The four program types mirror a traditional graphical rendering pipeline and are:</p>
+
+ <ul>
+ <li>Vertex</li>
+
+ <li>Fragment</li>
+
+ <li>Store</li>
+
+ <li>Raster</li>
+ </ul>
+
+ <p>Graphical scripts have more properties beyond a basic computational script, and they call the
+ 'rsg'-prefixed functions defined in the <code>rs_graphics.rsh</code> header file. A graphics
+ Renderscript can also set four pragmas that control the default bindings to the {@link
+ android.renderscript.RenderScriptGL} context when the script is executing:</p>
+
+ <ul>
+ <li>stateVertex</li>
+
+ <li>stateFragment</li>
+
+ <li>stateRaster</li>
+
+ <li>stateStore</li>
+ </ul>
+
+ <p>The possible values are <code>parent</code> or <code>default</code> for each pragma. Using
+ <code>default</code> says that when a script is executed, the bindings to the graphical context
+ are the system defaults. Using <code>parent</code> says that the state should be the same as it
+ is in the calling script. If this is a root script, the parent
+ state is taken from the bind points as set in the {@link android.renderscript.RenderScriptGL}
+ bind methods in the control environment (VM environment).</p>
+
+ <p>For example, you can define this at the top of your native Renderscript code:</p>
+ <pre>
+#pragma stateVertex(parent)
+#pragma stateStore(parent)
+</pre>
+
+ <p>The following table describes the major graphics specific APIs that are available to you:</p>
+
+ <table>
+ <tr>
+ <th>Android Object Type</th>
+
+ <th>Renderscript Native Type</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.ProgramVertex}</td>
+
+ <td>rs_program_vertex</td>
+
+ <td>
+ The Renderscript vertex program, also known as a vertex shader, describes the stage in the
+ graphics pipeline responsible for manipulating geometric data in a user-defined way. The
+ object is constructed by providing Renderscript with the following data:
+
+ <ul>
+ <li>An Element describing its varying inputs or attributes</li>
+
+ <li>GLSL shader string that defines the body of the program</li>
+
+ <li>a Type that describes the layout of an Allocation containing constant or uniform
+ inputs</li>
+ </ul>
+
+ <p>Once the program is created, bind it to the graphics context. It is then used for all
+ subsequent draw calls until you bind a new program. If the program has constant inputs, the
+ user needs to bind an allocation containing those inputs. The allocation’s type must match
+ the one provided during creation. The Renderscript library then does all the necessary
+ plumbing to send those constants to the graphics hardware. Varying inputs to the shader,
+ such as position, normal, and texture coordinates are matched by name between the input
+ Element and the Mesh object being drawn. The signatures don’t have to be exact or in any
+ strict order. As long as the input name in the shader matches a channel name and size
+ available on the mesh, the run-time would take care of connecting the two. Unlike OpenGL,
+ there is no need to link the vertex and fragment programs.</p>
+ <p> To bind shader constructs to the Program, declare a struct containing the necessary shader constants in your native Renderscript code.
+ This struct is generated into a reflected class that you can use as a constant input element
+ during the Program's creation. It is an easy way to create an instance of this struct as an allocation.
+ You would then bind this Allocation to the Program and the Renderscript system sends the data that
+ is contained in the struct to the hardware when necessary. To update shader constants, you change the values
+ in the Allocation and notify the native Renderscript code of the change.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.ProgramFragment}</td>
+
+ <td>rs_program_fragment</td>
+
+ <td>The Renderscript fragment program, also known as the fragment shader, is responsible for
+ manipulating pixel data in a user-defined way. It’s constructed from a GLSL shader string
+ containing the program body, textures inputs, and a Type object describing the constants used
+ by the program. Like the vertex programs, when an allocation with constant input values is
+ bound to the shader, its values are sent to the graphics program automatically. Note that the
+ values inside the allocation are not explicitly tracked. If they change between two draw
+ calls using the same program object, notify the runtime of that change by calling
+ rsgAllocationSyncAll so it could send the new values to hardware. Communication between the
+ vertex and fragment programs is handled internally in the GLSL code. For example, if the
+ fragment program is expecting a varying input called varTex0, the GLSL code inside the
+ program vertex must provide it.
+ <p> To bind shader constructs to the this Program, declare a struct containing the necessary shader constants in your native Renderscript code.
+ This struct is generated into a reflected class that you can use as a constant input element
+ during the Program's creation. It is an easy way to create an instance of this struct as an allocation.
+ You would then bind this Allocation to the Program and the Renderscript system sends the data that
+ is contained in the struct to the hardware when necessary. To update shader constants, you change the values
+ in the Allocation and notify the native Renderscript code of the change.</p></td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.ProgramStore}</td>
+
+ <td>rs_program_store</td>
+
+ <td>The Renderscript ProgramStore contains a set of parameters that control how the graphics
+ hardware writes to the framebuffer. It could be used to enable/disable depth writes and
+ testing, setup various blending modes for effects like transparency and define write masks
+ for color components.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.ProgramRaster}</td>
+
+ <td>rs_program_raster</td>
+
+ <td>Program raster is primarily used to specify whether point sprites are enabled and to
+ control the culling mode. By default back faces are culled.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.Sampler}</td>
+
+ <td>rs_sampler</td>
+
+ <td>A Sampler object defines how data is extracted from textures. Samplers are bound to
+ Program objects (currently only a Fragment Program) alongside the texture whose sampling they
+ control. These objects are used to specify such things as edge clamping behavior, whether
+ mip-maps are used and the amount of anisotropy required. There may be situations where
+ hardware limitations prevent the exact behavior from being matched. In these cases, the
+ runtime attempts to provide the closest possible approximation. For example, the user
+ requested 16x anisotropy, but only 8x was set because it’s the best available on the
+ hardware.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.Mesh}</td>
+
+ <td>rs_mesh</td>
+
+ <td>A collection of allocations that represent vertex data (positions, normals, texture
+ coordinates) and index data such as triangles and lines. Vertex data can be interleaved
+ within one allocation, provided separately as multiple allocation objects, or done as a
+ combination of the above. The layout of these allocations will be extracted from their
+ Elements. When a vertex channel name matches an input in the vertex program, Renderscript
+ automatically connects the two. Moreover, even allocations that cannot be directly mapped to
+ graphics hardware can be stored as part of the mesh. Such allocations can be used as a
+ working area for vertex-related computation and will be ignored by the hardware. Parts of the
+ mesh could be rendered with either explicit index sets or primitive types.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.renderscript.Font}</td>
+
+ <td>rs_font</td>
+
+ <td>
+ <p>This class gives you a way to draw hardware accelerated text. Internally, the glyphs are
+ rendered using the Freetype library, and an internal cache of rendered glyph bitmaps is
+ maintained. Each font object represents a combination of a typeface and point sizes.
+ Multiple font objects can be created to represent faces such as bold and italic and to
+ create different font sizes. During creation, the framework determines the device screen's
+ DPI to ensure proper sizing across multiple configurations.</p>
+
+ <p>Font rendering can impact performance. Even though though the state changes are
+ transparent to the user, they are happening internally. It is more efficient to render
+ large batches of text in sequence, and it is also more efficient to render multiple
+ characters at once instead of one by one.</p>
+
+ <p>Font color and transparency are not part of the font object and can be freely modified
+ in the script to suit the your needs. Font colors work as a state machine, and every new
+ call to draw text will use the last color set in the script.</p>
+ </td>
+ </tr>
+ </table>
+
+
+ <h2 id="developing">Developing a Renderscript application</h2>
+
+ <p>The basic workflow of developing a Renderscript application is:</p>
+
+ <ol>
+ <li>Analyze your application's requirements and figure out what you want to develop with
+ Renderscript. To take full advantage of Renderscript, you want to use it when the computation
+ or graphics performance you're getting with the normal Android system APIs is
+ insufficient.</li>
+
+ <li>Design the interface of your Renderscript code and implement it using the native
+ Renderscript APIs that are included in the Android SDK in
+ <code><sdk_root>/platforms/android-3.0/renderscript</code>.</li>
+
+ <li>Create an Android project as you would normally, in Eclipse or with the
+ <code>android</code> tool.</li>
+
+ <li>Place your Renderscript files in <code>src</code> folder of the Android project so that the
+ build tools can generate the reflective layer classes.</li>
+
+ <li>Create your application, calling the Renderscript through the reflected class layer when
+ you need to.</li>
+
+ <li>Build, install, and run your application as you would normally.</li>
+ </ol>
+
+ <p>To see how a simple Renderscript application is put together, see <a href="#hello-world">The
+ Hello World Renderscript Graphics Application</a>. The SDK also ships with many Renderscript
+ samples in the<code><sdk_root>/samples/android-3.0/</code> directory.</p>
+
+ <h3 id="hello-graphics">The Hello Graphics Application</h3>
+
+ <p>This small application demonstrates the structure of a simple Renderscript application. You
+ can model your Renderscript application after the basic structure of this application. You can
+ find the complete source in the SDK in the
+ <code><android-sdk>/platforms/android-3.0/samples/HelloWorldRS directory</code>. The
+ application uses Renderscript to draw the string, "Hello World!" to the screen and redraws the
+ text whenever the user touches the screen at the location of the touch. This application is only
+ a demonstration and you should not use the Renderscript system to do something this trivial. The
+ application contains the following source files:</p>
+
+ <ul>
+ <li><code>HelloWorld</code>: The main Activity for the application. This class is present to
+ provide Activity lifecycle management. It mainly delegates work to HelloWorldView, which is the
+ Renderscript surface that the sample actually draws on.</li>
+
+ <li><code>HelloWorldView</code>: The Renderscript surface that the graphics render on. If you
+ are using Renderscript for graphics rendering, you must have a surface to render on. If you are
+ using it for computatational operations only, then you do not need this.</li>
+
+ <li><code>HelloWorldRS</code>: The class that calls the native Renderscript code through high
+ level entry points that are generated by the Android build tools.</li>
+
+ <li><code>helloworld.rs</code>: The Renderscript native code that draws the text on the
+ screen.</li>
+
+ <li>
+ <p>The <code><project_root>/gen</code> directory contains the reflective layer classes
+ that are generated by the Android build tools. You will notice a
+ <code>ScriptC_helloworld</code> class, which is the reflective version of the Renderscript
+ and contains the entry points into the <code>helloworld.rs</code> native code. This file does
+ not appear until you run a build.</p>
+ </li>
+ </ul>
+
+ <p>Each file has its own distinct use. The following section demonstrates in detail how the
+ sample works:</p>
+
+ <dl>
+ <dt><code>helloworld.rs</code></dt>
+
+ <dd>
+ The native Renderscript code is contained in the <code>helloworld.rs</code> file. Every
+ <code>.rs</code> file must contain two pragmas that define the version of Renderscript
+ that it is using (1 is the only version for now), and the package name that the reflected
+ classes should be generated with. For example:
+<pre>
+#pragma version(1)
+
+#pragma rs java_package_name(com.my.package.name)
+</pre>
+ <p>An <code>.rs</code> file can also declare two special functions:</p>
+
+ <ul>
+ <li>
+ <code>init()</code>: This function is called once for each instance of this Renderscript
+ file that is loaded on the device, before the script is accessed in any other way by the
+ Renderscript system. The <code>init()</code> is ideal for doing one time setup after the
+ machine code is loaded such as initializing complex constant tables. The
+ <code>init()</code> function for the <code>helloworld.rs</code> script sets the initial
+ location of the text that is rendered to the screen:
+ <pre>
+void init(){
+ gTouchX = 50.0f;
+ gTouchY = 50.0f;
+}
+</pre>
+ </li>
+
+ <li>
+ <code>root()</code>: This function is the default worker function for this Renderscript
+ file. For graphics Renderscript applications, like this one, the Renderscript system
+ expects this function to render the frame that is going to be displayed. It is called
+ every time the frame refreshes. The <code>root()</code> function for the
+ <code>helloworld.rs</code> script sets the background color of the frame, the color of
+ the text, and then draws the text where the user last touched the screen:
+<pre>
+int root(int launchID) {
+ // Clear the background color
+ rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ // Tell the runtime what the font color should be
+ rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+ // Introduce ourselves to the world by drawing a greeting
+ // at the position that the user touched on the screen
+ rsgDrawText("Hello World!", gTouchX, gTouchY);
+
+ // Return value tells RS roughly how often to redraw
+ // in this case 20 ms
+ return 20;
+}
+</pre>
+
+ <p>The return value, <code>20</code>, is the desired frame refresh rate in milliseconds.
+ The real screen refresh rate depends on the hardware, computation, and rendering
+ complexity that the <code>root()</code> function has to execute. A value of
+ <code>0</code> tells the screen to render only once and to only render again when a
+ change has been made to one of the properties that are being modified by the Renderscript
+ code.</p>
+
+ <p>Besides the <code>init()</code> and <code>root()</code> functions, you can define the
+ other native functions, structs, data types, and any other logic for your Renderscript.
+ You can even define separate header files as <code>.rsh</code> files.</p>
+ </li>
+ </ul>
+ </dd>
+
+ <dt><code>ScriptC_helloworld</code></dt>
+
+ <dd>This class is generated by the Android build tools and is the reflected version of the
+ <code>helloworld.rs</code> Renderscript. It provides a a high level entry point into the
+ <code>helloworld.rs</code> native code by defining the corresponding methods that you can call
+ from Android system APIs.</dd>
+
+ <dt><code>helloworld.bc</code> bytecode</dt>
+
+ <dd>This file is the intermediate, platform-independent bytecode that gets compiled on the
+ device when the Renderscript application runs. It is generated by the Android build tools and
+ is packaged with the <code>.apk</code> file and subsequently compiled on the device at runtime.
+ This file is located in the <code><project_root>/res/raw/</code> directory and is named
+ <code>rs_filename.bc</code>. You need to bind these files to your Renderscript context before
+ call any Renderscript code from your Android application. You can reference them in your code
+ with <code>R.id.rs_filename</code>.</dd>
+
+ <dt><code>HelloWorldView</code> class</dt>
+
+ <dd>
+ This class represents the Surface View that the Renderscript graphics are drawn on. It does
+ some administrative tasks in the <code>ensureRenderScript()</code> method that sets up the
+ Renderscript system. This method creates a {@link android.renderscript.RenderScriptGL}
+ object, which represents the context of the Renderscript and creates a default surface to
+ draw on (you can set the surface properties such as alpha and bit depth in the {@link
+ android.renderscript.RenderScriptGL.SurfaceConfig} class ). When a {@link
+ android.renderscript.RenderScriptGL} is instantiated, this class calls the
+ <code>HelloRS</code> class and creates the instance of the actual Renderscript graphics
+ renderer.
+ <pre>
+// Renderscipt context
+private RenderScriptGL mRS;
+// Script that does the rendering
+private HelloWorldRS mRender;
+
+ private void ensureRenderScript() {
+ if (mRS == null) {
+ // Initialize Renderscript with desired surface characteristics.
+ // In this case, just use the defaults
+ RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+ mRS = createRenderScriptGL(sc);
+
+ // Create an instance of the Renderscript that does the rendering
+ mRender = new HelloWorldRS();
+ mRender.init(mRS, getResources());
+ }
+ }
+</pre>
+
+ <p>This class also handles the important lifecycle events and relays touch events to the
+ Renderscript renderer. When a user touches the screen, it calls the renderer,
+ <code>HelloWorldRS</code> and asks it to draw the text on the screen at the new location.</p>
+ <pre>
+public boolean onTouchEvent(MotionEvent ev) {
+ // Pass touch events from the system to the rendering script
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mRender.onActionDown((int)ev.getX(), (int)ev.getY());
+ return true;
+ }
+ return false;
+}
+</pre>
+ </dd>
+
+ <dt><code>HelloWorldRS</code></dt>
+
+ <dd>
+ This class represents the Renderscript renderer for the <code>HelloWorldView</code> Surface
+ View. It interacts with the native Renderscript code that is defined in
+ <code>helloworld.rs</code> through the interfaces exposed by <code>ScriptC_helloworld</code>.
+ To be able to call the native code, it creates an instance of the Renderscript reflected
+ class, <code>ScriptC_helloworld</code>. The reflected Renderscript object binds the
+ Renderscript bytecode (<code>R.raw.helloworld</code>) and the Renderscript context, {@link
+ android.renderscript.RenderScriptGL}, so the context knows to use the right Renderscript to
+ render its surface.
+ <pre>
+private Resources mRes;
+private RenderScriptGL mRS;
+private ScriptC_helloworld mScript;
+
+private void initRS() {
+ mScript = new ScriptC_helloworld(mRS, mRes, R.raw.helloworld);
+ mRS.bindRootScript(mScript);
+}
+</pre>
+ </dd>
+ </dl>
\ No newline at end of file
diff --git a/docs/html/guide/topics/graphics/view-animation.jd b/docs/html/guide/topics/graphics/view-animation.jd
new file mode 100644
index 0000000..ad27e1c
--- /dev/null
+++ b/docs/html/guide/topics/graphics/view-animation.jd
@@ -0,0 +1,190 @@
+page.title=View Animation
+@jd:body
+
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li><a href="#tween-animation">Tween animation</a></li>
+ <li><a href="#frame-animation">Frame animation</a></li>
+ </ol>
+
+ </div>
+ </div>
+
+ You can use View Animation in any View object to
+ perform tweened animation and frame by frame animation. Tween animation calculates the animation
+ given information such as the start point, end point, size, rotation, and other common aspects of
+ an animation. Frame by frame animation lets you load a series of Drawable resources one after
+ another to create an animation.
+
+ <h2 id="tween-animation">Tween Animation</h2>
+
+ <p>A tween animation can perform a series of simple transformations (position, size, rotation,
+ and transparency) on the contents of a View object. So, if you have a {@link
+ android.widget.TextView} object, you can move, rotate, grow, or shrink the text. If it has a
+ background image, the background image will be transformed along with the text. The {@link
+ android.view.animation animation package} provides all the classes used in a tween animation.</p>
+
+ <p>A sequence of animation instructions defines the tween animation, defined by either XML or
+ Android code. As with defining a layout, an XML file is recommended because it's more readable,
+ reusable, and swappable than hard-coding the animation. In the example below, we use XML. (To
+ learn more about defining an animation in your application code, instead of XML, refer to the
+ {@link android.view.animation.AnimationSet} class and other {@link
+ android.view.animation.Animation} subclasses.)</p>
+
+ <p>The animation instructions define the transformations that you want to occur, when they will
+ occur, and how long they should take to apply. Transformations can be sequential or simultaneous
+ - for example, you can have the contents of a TextView move from left to right, and then rotate
+ 180 degrees, or you can have the text move and rotate simultaneously. Each transformation takes a
+ set of parameters specific for that transformation (starting size and ending size for size
+ change, starting angle and ending angle for rotation, and so on), and also a set of common
+ parameters (for instance, start time and duration). To make several transformations happen
+ simultaneously, give them the same start time; to make them sequential, calculate the start time
+ plus the duration of the preceding transformation.</p>
+
+ <p>The animation XML file belongs in the <code>res/anim/</code> directory of your Android
+ project. The file must have a single root element: this will be either a single
+ <code><alpha></code>, <code><scale></code>, <code><translate></code>,
+ <code><rotate></code>, interpolator element, or <code><set></code> element that holds
+ groups of these elements (which may include another <code><set></code>). By default, all
+ animation instructions are applied simultaneously. To make them occur sequentially, you must
+ specify the <code>startOffset</code> attribute, as shown in the example below.</p>
+
+ <p>The following XML from one of the ApiDemos is used to stretch, then simultaneously spin and
+ rotate a View object.</p>
+ <pre>
+<set android:shareInterpolator="false">
+ <scale
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:fromXScale="1.0"
+ android:toXScale="1.4"
+ android:fromYScale="1.0"
+ android:toYScale="0.6"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillAfter="false"
+ android:duration="700" />
+ <set android:interpolator="@android:anim/decelerate_interpolator">
+ <scale
+ android:fromXScale="1.4"
+ android:toXScale="0.0"
+ android:fromYScale="0.6"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:startOffset="700"
+ android:duration="400"
+ android:fillBefore="false" />
+ <rotate
+ android:fromDegrees="0"
+ android:toDegrees="-45"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:startOffset="700"
+ android:duration="400" />
+ </set>
+</set>
+</pre>
+
+ <p>Screen coordinates (not used in this example) are (0,0) at the upper left hand corner, and
+ increase as you go down and to the right.</p>
+
+ <p>Some values, such as pivotX, can be specified relative to the object itself or relative to the
+ parent. Be sure to use the proper format for what you want ("50" for 50% relative to the parent,
+ or "50%" for 50% relative to itself).</p>
+
+ <p>You can determine how a transformation is applied over time by assigning an {@link
+ android.view.animation.Interpolator}. Android includes several Interpolator subclasses that
+ specify various speed curves: for instance, {@link android.view.animation.AccelerateInterpolator}
+ tells a transformation to start slow and speed up. Each one has an attribute value that can be
+ applied in the XML.</p>
+
+ <p>With this XML saved as <code>hyperspace_jump.xml</code> in the <code>res/anim/</code>
+ directory of the project, the following code will reference it and apply it to an {@link
+ android.widget.ImageView} object from the layout.</p>
+ <pre>
+ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
+Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
+spaceshipImage.startAnimation(hyperspaceJumpAnimation);
+</pre>
+
+ <p>As an alternative to <code>startAnimation()</code>, you can define a starting time for the
+ animation with <code>{@link android.view.animation.Animation#setStartTime(long)
+ Animation.setStartTime()}</code>, then assign the animation to the View with <code>{@link
+ android.view.View#setAnimation(android.view.animation.Animation) View.setAnimation()}</code>.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
+
+ <p class="note"><strong>Note:</strong> Regardless of how your animation may move or resize, the
+ bounds of the View that holds your animation will not automatically adjust to accommodate it.
+ Even so, the animation will still be drawn beyond the bounds of its View and will not be clipped.
+ However, clipping <em>will occur</em> if the animation exceeds the bounds of the parent View.</p>
+
+ <h2 id="frame-animation">Frame Animation</h2>
+
+ <p>This is a traditional animation in the sense that it is created with a sequence of different
+ images, played in order, like a roll of film. The {@link
+ android.graphics.drawable.AnimationDrawable} class is the basis for frame animations.</p>
+
+ <p>While you can define the frames of an animation in your code, using the {@link
+ android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished with a
+ single XML file that lists the frames that compose the animation. Like the tween animation above,
+ the XML file for this kind of animation belongs in the <code>res/drawable/</code> directory of
+ your Android project. In this case, the instructions are the order and duration for each frame of
+ the animation.</p>
+
+ <p>The XML file consists of an <code><animation-list></code> element as the root node and a
+ series of child <code><item></code> nodes that each define a frame: a drawable resource for
+ the frame and the frame duration. Here's an example XML file for a frame-by-frame animation:</p>
+ <pre>
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:oneshot="true">
+ <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
+ <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
+ <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
+</animation-list>
+</pre>
+
+ <p>This animation runs for just three frames. By setting the <code>android:oneshot</code>
+ attribute of the list to <var>true</var>, it will cycle just once then stop and hold on the last
+ frame. If it is set <var>false</var> then the animation will loop. With this XML saved as
+ <code>rocket_thrust.xml</code> in the <code>res/drawable/</code> directory of the project, it can
+ be added as the background image to a View and then called to play. Here's an example Activity,
+ in which the animation is added to an {@link android.widget.ImageView} and then animated when the
+ screen is touched:</p>
+ <pre>
+AnimationDrawable rocketAnimation;
+
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
+ rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
+ rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
+}
+
+public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ rocketAnimation.start();
+ return true;
+ }
+ return super.onTouchEvent(event);
+}
+</pre>
+
+ <p>It's important to note that the <code>start()</code> method called on the AnimationDrawable
+ cannot be called during the <code>onCreate()</code> method of your Activity, because the
+ AnimationDrawable is not yet fully attached to the window. If you want to play the animation
+ immediately, without requiring interaction, then you might want to call it from the <code>{@link
+ android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code> method in your
+ Activity, which will get called when Android brings your window into focus.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
+</body>
+</html>
diff --git a/docs/html/guide/topics/manifest/compatible-screens-element.jd b/docs/html/guide/topics/manifest/compatible-screens-element.jd
new file mode 100644
index 0000000..9fb0fd2
--- /dev/null
+++ b/docs/html/guide/topics/manifest/compatible-screens-element.jd
@@ -0,0 +1,108 @@
+page.title=<compatible-screens>
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd>
+<pre>
+<<a href="#compatible-screens">compatible-screens</a>>
+ <<a href="#screen">screen</a> android:<a href="#screenSize">screenSize</a>=["small" | "normal" | "large" | "xlarge"]
+ android:<a href="#screenDensity">screenDensity</a>=["ldpi" | "mdpi" | "hdpi" | "xhdpi"] />
+ ...
+</compatible-screens>
+</pre>
+</dd>
+
+<dt>contained in:</dt>
+<dd><code><a
+href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd>
+
+<dt>description:</dt>
+<dd>Specifies each screen configuration with which the application is compatible. Only one instance
+of the {@code <compatible-screens>} element is allowed in the manifest, but it can
+contain multiple <code><screen></code> elements. Each <code><screen></code> element
+specifies a specific screen size-density combination with which the application is compatible.
+
+ <p>The Android system <em>does not</em> read the {@code <compatible-screens>} manifest
+element (neither at install-time nor at runtime). This element is informational only and may be used
+by external services (such as Android Market) to better understand the application's compatibility
+with specific screen configurations and enable filtering for users. Any screen configuration that is
+<em>not</em> declared in this element is a screen with which the application is <em>not</em>
+compatible. Thus, external services (such as Android Market) should not provide the application to
+devices with such screens.</p>
+
+ <p class="caution"><strong>Caution:</strong> Normally, <strong>you should not use this manifest
+element</strong>. Using this element can dramatically reduce the potential user base for your
+application, by not allowing users to install your application if they have a device with a screen
+configuration that you have not listed. You should use it only as a last resort, when the
+application absolutely does not work with all screen configurations. Instead of using this element,
+you should follow the guide to <a href="{@docRoot}guide/practices/screens_support.html">Supporting
+Multiple Screens</a>, in order to provide complete support for multiple screens, by adding
+alternative resources for different screen sizes and densities.</p>
+
+ <p>If you want to set only a minimum screen <em>size</em> for your your application, then you
+should use the <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+<supports-screens>}</a> element. For example, if you want your application to be available
+only for <em>large</em> and <em>xlarge</em> screen devices, the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+<supports-screens>}</a> element allows you to declare that your application does not
+support <em>small</em> and <em>normal</em> screen sizes. External services (such as Android
+Market) will filter your application accordingly. You can also use the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+<supports-screens>}</a> element to declare whether the system should resize your
+application for different screen sizes.</p>
+
+ <p>Also see the <a href="{@docRoot}guide/appendix/market-filters.html">Market Filters</a>
+document for more information about how Android Market filters applications using this and
+other manifest elements.</p>
+
+</dd>
+
+<dt>child elements:</dt>
+<dd>
+ <dl class="tag-list">
+
+ <dt id="screen">{@code <screen>}</dt>
+ <dd>Specifies a single screen configuration with which the application is compatible.
+ <p>At least one instance of this element must be placed inside the {@code
+<compatible-screens>} element. This element <em>must include both</em> the {@code
+android:screenSize} and {@code android:screenDensity} attributes (if you do not declare both
+attributes, then the element is ignored).</p>
+
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt id="screenSize"><code>android:screenSize</code></dt>
+ <dd><b>Required.</b> Specifies the screen size for this screen configuration.
+ <p>Accepted values:</p>
+ <ul>
+ <li>{@code small}</li>
+ <li>{@code normal}</li>
+ <li>{@code large}</li>
+ <li>{@code xlarge}</li>
+ </ul>
+ <p>For information about the different screen sizes, see <a
+href="{@docRoot}guide/practices/screens_support.html#range">Supporting Multiple Screens</a>.</p>
+ </dd>
+ <dt id="screenDensity"><code>android:screenDensity</code></dt>
+ <dd><b>Required.</b> Specifies the screen density for this screen configuration.
+ <p>Accepted values:</p>
+ <ul>
+ <li>{@code ldpi}</li>
+ <li>{@code mdpi}</li>
+ <li>{@code hdpi}</li>
+ <li>{@code xhdpi}</li>
+ </ul>
+ <p>For information about the different screen densities, see <a
+href="{@docRoot}guide/practices/screens_support.html#range">Supporting Multiple Screens</a>.</p>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+</dd>
+<dt>introduced in:</dt>
+<dd>API Level 9</dd>
+<dt>see also:</dt>
+<dd><a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></dd>
+<dd><a href="{@docRoot}guide/appendix/market-filters.html">Market Filters</a></dd>
+</dl>
diff --git a/docs/html/guide/topics/manifest/supports-screens-element.jd b/docs/html/guide/topics/manifest/supports-screens-element.jd
index 64a7a58..92c769e 100644
--- a/docs/html/guide/topics/manifest/supports-screens-element.jd
+++ b/docs/html/guide/topics/manifest/supports-screens-element.jd
@@ -6,7 +6,8 @@
<dt>syntax:</dt>
<dd>
<pre class="stx">
-<supports-screens android:<a href="#small">smallScreens</a>=["true" | "false"]
+<supports-screens android:<a href="#resizeable">resizeable</a>=["true" | "false"]
+ android:<a href="#small">smallScreens</a>=["true" | "false"]
android:<a href="#normal">normalScreens</a>=["true" | "false"]
android:<a href="#large">largeScreens</a>=["true" | "false"]
android:<a href="#xlarge">xlargeScreens</a>=["true" | "false"]
@@ -19,17 +20,33 @@
<dt>description:</dt>
<dd>Lets you specify the screen dimensions the
-application supports. By default a modern application (using API Level 4 or higher) supports all
-screen sizes and must explicitly disable certain screen sizes here;
-older applications are assumed to support only the "normal"
-screen size. Note that screen size is a separate axis from
-density. Screen size is determined as the available pixels to an application
-after density scaling has been applied.
+application supports. By default, a modern application (using API Level 4 or higher) supports all
+screen sizes; older applications are assumed to support only the "normal" screen size. Screen
+size is determined as the available pixels to an application after density scaling has been
+applied. (Note that screen size is a separate axis from screen density.)
-<p>Based on the target device screen density, the Android
-framework will scale down assets by a factor of 0.75 (low dpi screens)
-or scale them up by a factor of 1.5 (high dpi screens).
-The screen density is expressed as dots-per-inch (dpi).</p>
+<p>An application "supports" a given screen size if it fills the entire screen and works as
+expected. By default, the system will resize your application to fill the screen, if you have set
+either <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+minSdkVersion}</a> or <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+targetSdkVersion}</a> to {@code "4"} or higher. Resizing works well for most applications and
+you don't have to do any extra work to make your application work on larger screens.</p>
+
+<p>In addition to allowing the system to resize your application, you can add additional support
+for different screen sizes by providing <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">alternative
+layout resources</a> for different sizes. For instance, you might want to modify the layout
+of an activity when it is on a tablet or similar device that has an <em>xlarge</em> screen.</p>
+
+<p>If your application does not support <em>large</em> or <em>xlarge</em> screens, then you should
+declare that it is not resizeable by setting <a href="#resizeable">{@code android:resizeable}</a> to
+{@code "false"}, so that the system will not resize your application on larger screens.</p>
+
+<p>If your application does not support <em>small</em> screens, then
+there isn't much the system can do to make the application work well on a smaller screen, so
+external services (such as Android Market) should not allow users to install the application on such
+screens.</p>
+
<p>For more information, see
<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.</p>
@@ -38,16 +55,40 @@
<dt>attributes:</dt>
<dd>
-<dl class="attr"><dt><a name="small"></a>{@code android:smallScreens}</dt>
+<dl class="attr">
+
+ <dt><a name="resizeable"></a>{@code android:resizeable}</dt>
+ <dd>Indicates whether the application is resizeable for different screen sizes. This attribute is
+true, by default, if you have set either <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> to
+{@code "4"} or higher. Otherwise, it is false by default. If set false, the system will not resize
+your application when run on <em>large</em> or <em>xlarge</em> screens. Instead, the
+application appears in a "postage stamp" that equals the <em>normal</em> screen size that your
+application does support. This is less than an ideal experience for users, because the
+application appears smaller than the available screen, but it might help your application run
+normally if it were designed only for the <em>normal</em> screen size and some behaviors do not work
+when resized.</p>
+ <p>To provide the best experience on all screen sizes, you should allow resizing and, if your
+application does not work well on larger screens, follow the guide to <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a> to enable
+additional screen support.</p>
+ </dd>
+
+
+ <dt><a name="small"></a>{@code android:smallScreens}</dt>
<dd>Indicates whether the application supports smaller screen form-factors.
A small screen is defined as one with a smaller aspect ratio than
the "normal" (traditional HVGA) screen. An application that does
not support small screens <em>will not be available</em> for
- small screen devices, because there is little the platform can do
- to make such an application work on a smaller screen. If the application has set the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element's
-{@code android:minSdkVersion} or {@code android:targetSdkVersion} attribute to "4" or higher,
-the default value for this is "true", any value less than "4" results in this set to "false".
+ small screen devices from external services (such as Android Market), because there is little
+the platform can do
+ to make such an application work on a smaller screen. If the application has set either <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> to
+{@code "4"} or higher,
+the default value for this is {@code "true"}, any value less than {@code "4"} results in this set to
+{@code "false"}.
</dd>
<dt><a name="normal"></a>{@code android:normalScreens}</dt>
@@ -61,38 +102,44 @@
<dt><a name="large"></a>{@code android:largeScreens}</dt>
<dd>Indicates whether the application supports larger screen form-factors.
A large screen is defined as a screen that is significantly larger
- than a "normal" phone screen, and thus may require some special care
- on the application's part to make good use of it. An application that
- does not support large screens (declares this "false")—but does support "normal" or
-"small" screens—will be placed as a "postage stamp" on
- a large screen, so that it retains the dimensions it was originally
- designed for. If the application has set the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element's
-{@code android:minSdkVersion} or {@code android:targetSdkVersion} attribute to "4" or higher,
-the default value for this is "true", any value less than "4" results in this set to "false".
+ than a "normal" phone screen, and thus might require some special care
+ on the application's part to make good use of it, though it may rely on resizing by the
+system to fill the screen. If the application has set either <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> to
+{@code "4"} or higher,
+the default value for this is {@code "true"}, any value less than {@code "4"} results in this set to
+{@code "false"}.
</dd>
-
+
<dt><a name="xlarge"></a>{@code android:xlargeScreens}</dt>
<dd>Indicates whether the application supports extra large screen form-factors.
An xlarge screen is defined as a screen that is significantly larger
than a "large" screen, such as a tablet (or something larger) and may require special care
- on the application's part to make good use of it. An application that
- does not support xlarge screens (declares this "false")—but does support "large",
-"normal", or "small" screens—will be placed as a "postage stamp" on
- an xlarge screen, so that it retains the dimensions it was originally
- designed for. If the application has set the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element's
-{@code android:minSdkVersion} or {@code android:targetSdkVersion} attribute to "4" or higher,
-the default value for this is "true", any value less than "4" results in this set to "false".
+ on the application's part to make good use of it, though it may rely on resizing by the
+system to fill the screen. If the application has set either <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> to
+{@code "4"} or higher,
+the default value for this is {@code "true"}, any value less than {@code "4"} results in this set to
+{@code "false"}.
<p>This attribute was introduced in API Level 9.</p>
</dd>
<dt><a name="any"></a>{@code android:anyDensity}</dt>
<dd>Indicates whether the application includes resources to accommodate any screen
density. Older applications (before API Level 4) are assumed unable to
- accomodate all densities and this is "false" by default. Applications using
- API Level 4 or higher are assumed able to and this is "true" by default.
+ accomodate all densities and this is {@code "false"} by default. If the application has set
+either <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> to
+{@code "4"} or higher,
+the default value for this is {@code "true"}. Otherwise, it is {@code "false"}.
You can explicitly supply your abilities here.
+ <p>Based on the "standard" device screen density (medium dpi), the Android framework will scale
+down application assets by a factor of 0.75 (low dpi screens) or scale them up by a factor of 1.5
+(high dpi screens), when you don't provide alternative resources for a specifc screen density. The
+screen density is expressed as dots-per-inch (dpi).</p>
</dd>
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 5242126..0828e8b 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -644,33 +644,46 @@
</tr>
<tr>
- <td rowspan="4">Touchscreen</td>
+ <td rowspan="5">Touchscreen</td>
+ <td><code>android.hardware.faketouch</code></td>
+ <td>The application uses basic touch interaction events, such as "click down", "click
+up", and drag.</td>
+ <td>When declared, this indicates that the application is compatible with a device that offers an
+emulated touchscreen (or better). A device that offers an emulated touchscreen provides a user input
+system that can emulate a subset of touchscreen capabilities. An example of such an input system is
+a mouse or remote control that drives an on-screen cursor. If your application does not require
+complicated gestures and you want your application available to devices with an emulated
+touchscreen, you should declare this feature.</td>
+</tr>
+<tr>
<td><code>android.hardware.touchscreen</code></td>
- <td>The application uses touchscreen capabilities on the device.</td>
+ <td>The application uses touchscreen capabilities, for gestures more interactive
+than basic touches, such as a fling. This is a superset of the faketouch features.</td>
<td></td>
</tr>
<tr>
<td><code>android.hardware.touchscreen.multitouch</code></td>
- <td>Subfeature. The application uses basic two-point multitouch capabilities on the device
-screen.</td>
+ <td>The application uses basic two-point multitouch capabilities on the device
+screen, such as for pinch gestures, but does not need to track touches independently. This
+is a superset of touchscreen features.</td>
<td>If declared with the <code>"android:required="true"</code> attribute, this
-subfeature implicitly declares the <code>android.hardware.touchscreen</code>
+implicitly declares the <code>android.hardware.touchscreen</code>
parent feature. </td>
</tr>
<tr>
<td><code>android.hardware.touchscreen.multitouch.distinct</code></td>
<td>Subfeature. The application uses advanced multipoint multitouch
capabilities on the device screen, such as for tracking two or more points fully
-independently.</td>
+independently. This is a superset of multitouch features.</td>
<td rowspan="2">If declared with the <code>"android:required="true"</code> attribute, this
-subfeature implicitly declares the
+implicitly declares the
<code>android.hardware.touchscreen.multitouch</code> parent feature. </td>
</tr>
<tr>
<td><code>android.hardware.touchscreen.multitouch.jazzhand</code></td>
- <td>Subfeature. The application uses advanced multipoint multitouch
+ <td>The application uses advanced multipoint multitouch
capabilities on the device screen, for tracking up to five points fully
-independently.</td>
+independently. This is a superset of distinct multitouch features.</td>
</tr>
<tr>
diff --git a/docs/html/guide/topics/media/index.jd b/docs/html/guide/topics/media/index.jd
index e355212..b6d1629 100644
--- a/docs/html/guide/topics/media/index.jd
+++ b/docs/html/guide/topics/media/index.jd
@@ -148,70 +148,209 @@
<h2 id="capture">Audio Capture</h2>
<p>Audio capture from the device is a bit more complicated than audio/video playback, but still fairly simple:</p>
<ol>
- <li>Create a new instance of {@link android.media.MediaRecorder
- android.media.MediaRecorder} using <code>new</code></li>
- <li>Create a new instance of {@link android.content.ContentValues
- android.content.ContentValues} and put in some standard properties like
- <code>TITLE</code>, <code>TIMESTAMP</code>, and the all important
- <code>MIME_TYPE</code></li>
- <li>Create a file path for the data to go to (you can use {@link
- android.content.ContentResolver android.content.ContentResolver} to
- create an entry in the Content database and get it to assign a path
- automatically which you can then use)</li>
- <li>Set the audio source using {@link android.media.MediaRecorder#setAudioSource
- MediaRecorder.setAudioSource()}. You will probably want to use
+ <li>Create a new instance of {@link android.media.MediaRecorder android.media.MediaRecorder} using <code>new</code></li>
+ <li>Set the audio source using
+ {@link android.media.MediaRecorder#setAudioSource MediaRecorder.setAudioSource()}. You will probably want to use
<code>MediaRecorder.AudioSource.MIC</code></li>
- <li>Set output file format using {@link
- android.media.MediaRecorder#setOutputFormat MediaRecorder.setOutputFormat()}
+ <li>Set output file format using
+ {@link android.media.MediaRecorder#setOutputFormat MediaRecorder.setOutputFormat()}
+ </li>
+ <li>Set output file name using
+ {@link android.media.MediaRecorder#setOutputFile MediaRecorder.setOutputFile()}
</li>
<li>Set the audio encoder using
{@link android.media.MediaRecorder#setAudioEncoder MediaRecorder.setAudioEncoder()}
</li>
- <li>Call {@link android.media.MediaRecorder#prepare prepare()}
+ <li>Call {@link android.media.MediaRecorder#prepare MediaRecorder.prepare()}
on the MediaRecorder instance.</li>
<li>To start audio capture, call
- {@link android.media.MediaRecorder#start start()}. </li>
- <li>To stop audio capture, call {@link android.media.MediaRecorder#stop stop()}.
+ {@link android.media.MediaRecorder#start MediaRecorder.start()}. </li>
+ <li>To stop audio capture, call {@link android.media.MediaRecorder#stop MediaRecorder.stop()}.
<li>When you are done with the MediaRecorder instance, call
-{@link android.media.MediaRecorder#release release()} on it. </li>
+{@link android.media.MediaRecorder#release MediaRecorder.release()} on it. Calling
+{@link android.media.MediaRecorder#release MediaRecorder.release()} is always recommended to
+free the resource immediately.</li>
</ol>
-<h3>Example: Audio Capture Setup and Start</h3>
-<p>The example below illustrates how to set up, then start audio capture.</p>
+<h3>Example: Record audio and play the recorded audio</h3>
+<p>The example class below illustrates how to set up, start and stop audio capture, and to play the recorded audio file.</p>
<pre>
- recorder = new MediaRecorder();
- ContentValues values = new ContentValues(3);
+/*
+ * The application needs to have the permission to write to external storage
+ * if the output file is written to the external storage, and also the
+ * permission to record audio. These permissions must be set in the
+ * application's AndroidManifest.xml file, with something like:
+ *
+ * <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ * <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ *
+ */
+package com.android.audiorecordtest;
- values.put(MediaStore.MediaColumns.TITLE, SOME_NAME_HERE);
- values.put(MediaStore.MediaColumns.TIMESTAMP, System.currentTimeMillis());
- values.put(MediaStore.MediaColumns.MIME_TYPE, recorder.getMimeContentType());
-
- ContentResolver contentResolver = new ContentResolver();
-
- Uri base = MediaStore.Audio.INTERNAL_CONTENT_URI;
- Uri newUri = contentResolver.insert(base, values);
-
- if (newUri == null) {
- // need to handle exception here - we were not able to create a new
- // content entry
+import android.app.Activity;
+import android.widget.LinearLayout;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.content.Context;
+import android.util.Log;
+import android.media.MediaRecorder;
+import android.media.MediaPlayer;
+
+import java.io.IOException;
+
+
+public class AudioRecordTest extends Activity
+{
+ private static final String LOG_TAG = "AudioRecordTest";
+ private static String mFileName = null;
+
+ private RecordButton mRecordButton = null;
+ private MediaRecorder mRecorder = null;
+
+ private PlayButton mPlayButton = null;
+ private MediaPlayer mPlayer = null;
+
+ private void onRecord(boolean start) {
+ if (start) {
+ startRecording();
+ } else {
+ stopRecording();
+ }
}
-
- String path = contentResolver.getDataFilePath(newUri);
- // could use setPreviewDisplay() to display a preview to suitable View here
-
- recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- recorder.setOutputFile(path);
-
- recorder.prepare();
- recorder.start();
+ private void onPlay(boolean start) {
+ if (start) {
+ startPlaying();
+ } else {
+ stopPlaying();
+ }
+ }
+
+ private void startPlaying() {
+ mPlayer = new MediaPlayer();
+ try {
+ mPlayer.setDataSource(mFileName);
+ mPlayer.prepare();
+ mPlayer.start();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "prepare() failed");
+ }
+ }
+
+ private void stopPlaying() {
+ mPlayer.release();
+ mPlayer = null;
+ }
+
+ private void startRecording() {
+ mRecorder = new MediaRecorder();
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFile(mFileName);
+ mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+
+ try {
+ mRecorder.prepare();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "prepare() failed");
+ }
+
+ mRecorder.start();
+ }
+
+ private void stopRecording() {
+ mRecorder.stop();
+ mRecorder.release();
+ mRecorder = null;
+ }
+
+ class RecordButton extends Button {
+ boolean mStartRecording = true;
+
+ OnClickListener clicker = new OnClickListener() {
+ public void onClick(View v) {
+ onRecord(mStartRecording);
+ if (mStartRecording) {
+ setText("Stop recording");
+ } else {
+ setText("Start recording");
+ }
+ mStartRecording = !mStartRecording;
+ }
+ };
+
+ public RecordButton(Context ctx) {
+ super(ctx);
+ setText("Start recording");
+ setOnClickListener(clicker);
+ }
+ }
+
+ class PlayButton extends Button {
+ boolean mStartPlaying = true;
+
+ OnClickListener clicker = new OnClickListener() {
+ public void onClick(View v) {
+ onPlay(mStartPlaying);
+ if (mStartPlaying) {
+ setText("Stop playing");
+ } else {
+ setText("Start playing");
+ }
+ mStartPlaying = !mStartPlaying;
+ }
+ };
+
+ public PlayButton(Context ctx) {
+ super(ctx);
+ setText("Start playing");
+ setOnClickListener(clicker);
+ }
+ }
+
+ public AudioRecordTest() {
+ mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
+ mFileName += "/audiorecordtest.3gp";
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ LinearLayout ll = new LinearLayout(this);
+ mRecordButton = new RecordButton(this);
+ ll.addView(mRecordButton,
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 0));
+ mPlayButton = new PlayButton(this);
+ ll.addView(mPlayButton,
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 0));
+ setContentView(ll);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mRecorder != null) {
+ mRecorder.release();
+ mRecorder = null;
+ }
+
+ if (mPlayer != null) {
+ mPlayer.release();
+ mPlayer = null;
+ }
+ }
+}
</pre>
-<h3>Stop Recording</h3>
-<p>Based on the example above, here's how you would stop audio capture. </p>
-<pre>
- recorder.stop();
- recorder.release();
-</pre>
+
diff --git a/docs/html/guide/topics/providers/loaders.jd b/docs/html/guide/topics/providers/loaders.jd
new file mode 100644
index 0000000..c54656c
--- /dev/null
+++ b/docs/html/guide/topics/providers/loaders.jd
@@ -0,0 +1,492 @@
+page.title=Using Loaders
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#summary">Loader API Summary</a></li>
+ <li><a href="#app">Using Loaders in an Application</a>
+ <ol>
+ <li><a href="#requirements"></a></li>
+ <li><a href="#starting">Starting a Loader</a></li>
+ <li><a href="#restarting">Restarting a Loader</a></li>
+ <li><a href="#callback">Using the LoaderManager Callbacks</a></li>
+ </ol>
+ </li>
+ <li><a href="#example">Example</a>
+ <ol>
+ <li><a href="#more_examples">More Examples</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.app.LoaderManager}</li>
+ <li>{@link android.content.Loader}</li>
+
+ </ol>
+
+ <h2>Related samples</h2>
+ <ol>
+ <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentCursorLoader.html"> FragmentCursorLoader</a></li>
+ <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a></li>
+ </ol>
+ </div>
+</div>
+
+<p>Introduced in Android 3.0, loaders make it easy to asynchronously load data
+in an activity or fragment. Loaders have these characteristics:</p>
+ <ul>
+ <li>They are available to every {@link android.app.Activity} and {@link
+android.app.Fragment}.</li>
+ <li>They provide asynchronous loading of data.</li>
+ <li>They monitor the source of their data and deliver new results when the
+content changes.</li>
+ <li>They automatically reconnect to the last loader's cursor when being
+recreated after a configuration change. Thus, they don't need to re-query their
+data.</li>
+ </ul>
+
+<h2 id="summary">Loader API Summary</h2>
+
+<p>There are multiple classes and interfaces that may be involved in using
+loaders in an application. They are summarized in this table:</p>
+
+<table>
+ <tr>
+ <th>Class/Interface</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>{@link android.app.LoaderManager}</td>
+ <td>An abstract class associated with an {@link android.app.Activity} or
+{@link android.app.Fragment} for managing one or more {@link
+android.content.Loader} instances. This helps an application manage
+longer-running operations in conjunction with the {@link android.app.Activity}
+or {@link android.app.Fragment} lifecycle; the most common use of this is with a
+{@link android.content.CursorLoader}, however applications are free to write
+their own loaders for loading other types of data.
+ <br />
+ <br />
+ There is only one {@link android.app.LoaderManager} per activity or fragment. But a {@link android.app.LoaderManager} can have
+multiple loaders.</td>
+ </tr>
+ <tr>
+ <td>{@link android.app.LoaderManager.LoaderCallbacks}</td>
+ <td>A callback interface for a client to interact with the {@link
+android.app.LoaderManager}. For example, you use the {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
+callback method to create a new loader.</td>
+ </tr>
+ <tr>
+ <td>{@link android.content.Loader}</td>
+ <td>An abstract class that performs asynchronous loading of data. This is
+the base class for a loader. You would typically use {@link
+android.content.CursorLoader}, but you can implement your own subclass. While
+loaders are active they should monitor the source of their data and deliver new
+results when the contents change. </td>
+ </tr>
+ <tr>
+ <td>{@link android.content.AsyncTaskLoader}</td>
+ <td>Abstract loader that provides an {@link android.os.AsyncTask} to do the work.</td>
+ </tr>
+ <tr>
+ <td>{@link android.content.CursorLoader}</td>
+ <td>A subclass of {@link android.content.AsyncTaskLoader} that queries the
+{@link android.content.ContentResolver} and returns a {@link
+android.database.Cursor}. This class implements the {@link
+android.content.Loader} protocol in a standard way for querying cursors,
+building on {@link android.content.AsyncTaskLoader} to perform the cursor query
+on a background thread so that it does not block the application's UI. Using
+this loader is the best way to asynchronously load data from a {@link
+android.content.ContentProvider}, instead of performing a managed query through
+the fragment or activity's APIs.</td>
+ </tr>
+</table>
+
+<p>The classes and interfaces in the above table are the essential components
+you'll use to implement a loader in your application. You won't need all of them
+for each loader you create, but you'll always need a reference to the {@link
+android.app.LoaderManager} in order to initialize a loader and an implementation
+of a {@link android.content.Loader} class such as {@link
+android.content.CursorLoader}. The following sections show you how to use these
+classes and interfaces in an application.</p>
+
+<h2 id ="app">Using Loaders in an Application</h2>
+<p>This section describes how to use loaders in an Android application. An
+application that uses loaders typically includes the following:</p>
+<ul>
+ <li>An {@link android.app.Activity} or {@link android.app.Fragment}.</li>
+ <li>An instance of the {@link android.app.LoaderManager}.</li>
+ <li>A {@link android.content.CursorLoader} to load data backed by a {@link
+android.content.ContentProvider}. Alternatively, you can implement your own subclass
+of {@link android.content.Loader} or {@link android.content.AsyncTaskLoader} to
+load data from some other source.</li>
+ <li>An implementation for {@link android.app.LoaderManager.LoaderCallbacks}.
+This is where you create new loaders and manage your references to existing
+loaders.</li>
+<li>A way of displaying the loader's data, such as a {@link
+android.widget.SimpleCursorAdapter}.</li>
+ <li>A data source, such as a {@link android.content.ContentProvider}, when using a
+{@link android.content.CursorLoader}.</li>
+</ul>
+<h3 id="starting">Starting a Loader</h3>
+
+<p>The {@link android.app.LoaderManager} manages one or more {@link
+android.content.Loader} instances within an {@link android.app.Activity} or
+{@link android.app.Fragment}. There is only one {@link
+android.app.LoaderManager} per activity or fragment.</p>
+
+<p>You typically
+initialize a {@link android.content.Loader} within the activity's {@link
+android.app.Activity#onCreate onCreate()} method, or within the fragment's
+{@link android.app.Fragment#onActivityCreated onActivityCreated()} method. You
+do this as follows:</p>
+
+<pre>// Prepare the loader. Either re-connect with an existing one,
+// or start a new one.
+getLoaderManager().initLoader(0, null, this);</pre>
+
+<p>The {@link android.app.LoaderManager#initLoader initLoader()} method takes
+the following parameters:</p>
+<ul>
+ <li>A unique ID that identifies the loader. In this example, the ID is 0.</li>
+<li>Optional arguments to supply to the loader at
+construction (<code>null</code> in this example).</li>
+
+<li>A {@link android.app.LoaderManager.LoaderCallbacks} implementation, which
+the {@link android.app.LoaderManager} calls to report loader events. In this
+example, the local class implements the {@link
+android.app.LoaderManager.LoaderCallbacks} interface, so it passes a reference
+to itself, {@code this}.</li>
+</ul>
+<p>The {@link android.app.LoaderManager#initLoader initLoader()} call ensures that a loader
+is initialized and active. It has two possible outcomes:</p>
+<ul>
+ <li>If the loader specified by the ID already exists, the last created loader
+is reused.</li>
+ <li>If the loader specified by the ID does <em>not</em> exist,
+{@link android.app.LoaderManager#initLoader initLoader()} triggers the
+{@link android.app.LoaderManager.LoaderCallbacks} method {@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}.
+This is where you implement the code to instantiate and return a new loader.
+For more discussion, see the section <a
+href="#onCreateLoader">onCreateLoader</a>.</li>
+</ul>
+<p>In either case, the given {@link android.app.LoaderManager.LoaderCallbacks}
+implementation is associated with the loader, and will be called when the
+loader state changes. If at the point of this call the caller is in its
+started state, and the requested loader already exists and has generated its
+data, then the system calls {@link
+android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
+immediately (during {@link android.app.LoaderManager#initLoader initLoader()}),
+so you must be prepared for this to happen. See <a href="#onLoadFinished">
+onLoadFinished</a> for more discussion of this callback</p>
+
+<p>Note that the {@link android.app.LoaderManager#initLoader initLoader()}
+method returns the {@link android.content.Loader} that is created, but you don't
+need to capture a reference to it. The {@link android.app.LoaderManager} manages
+the life of the loader automatically. The {@link android.app.LoaderManager}
+starts and stops loading when necessary, and maintains the state of the loader
+and its associated content. As this implies, you rarely interact with loaders
+directly (though for an example of using loader methods to fine-tune a loader's
+behavior, see the <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> sample).
+You most commonly use the {@link
+android.app.LoaderManager.LoaderCallbacks} methods to intervene in the loading
+process when particular events occur. For more discussion of this topic, see <a
+href="#callback">Using the LoaderManager Callbacks</a>.</p>
+
+<h3 id="restarting">Restarting a Loader</h3>
+
+<p>When you use {@link android.app.LoaderManager#initLoader initLoader()}, as
+shown above, it uses an existing loader with the specified ID if there is one.
+If there isn't, it creates one. But sometimes you want to discard your old data
+and start over.</p>
+
+<p>To discard your old data, you use {@link
+android.app.LoaderManager#restartLoader restartLoader()}. For example, this
+implementation of {@link android.widget.SearchView.OnQueryTextListener} restarts
+the loader when the user's query changes. The loader needs to be restarted so
+that it can use the revised search filter to do a new query:</p>
+
+<pre>
+public boolean onQueryTextChanged(String newText) {
+ // Called when the action bar search text has changed. Update
+ // the search filter, and restart the loader to do a new query
+ // with this filter.
+ mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+ getLoaderManager().restartLoader(0, null, this);
+ return true;
+}</pre>
+
+<h3 id="callback">Using the LoaderManager Callbacks</h3>
+
+<p>{@link android.app.LoaderManager.LoaderCallbacks} is a callback interface
+that lets a client interact with the {@link android.app.LoaderManager}. </p>
+<p>Loaders, in particular {@link android.content.CursorLoader}, are expected to
+retain their data after being stopped. This allows applications to keep their
+data across the activity or fragment's {@link android.app.Activity#onStop
+onStop()} and {@link android.app.Activity#onStart onStart()} methods, so that
+when users return to an application, they don't have to wait for the data to
+reload. You use the {@link android.app.LoaderManager.LoaderCallbacks} methods
+when to know when to create a new loader, and to tell the application when it is
+ time to stop using a loader's data.</p>
+
+<p>{@link android.app.LoaderManager.LoaderCallbacks} includes these
+methods:</p>
+<ul>
+ <li>{@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} —
+Instantiate and return a new {@link android.content.Loader} for the given ID.
+</li></ul>
+<ul>
+ <li> {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
+— Called when a previously created loader has finished its load.
+</li></ul>
+<ul>
+ <li>{@link android.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}
+ — Called when a previously created loader is being reset, thus making its
+data unavailable.
+</li>
+</ul>
+<p>These methods are described in more detail in the following sections.</p>
+
+<h4 id ="onCreateLoader">onCreateLoader</h4>
+
+<p>When you attempt to access a loader (for example, through {@link
+android.app.LoaderManager#initLoader initLoader()}), it checks to see whether
+the loader specified by the ID exists. If it doesn't, it triggers the {@link
+android.app.LoaderManager.LoaderCallbacks} method {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}. This
+is where you create a new loader. Typically this will be a {@link
+android.content.CursorLoader}, but you can implement your own {@link
+android.content.Loader} subclass. </p>
+
+<p>In this example, the {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
+callback method creates a {@link android.content.CursorLoader}. You must build
+the {@link android.content.CursorLoader} using its constructor method, which
+requires the complete set of information needed to perform a query to the {@link
+android.content.ContentProvider}. Specifically, it needs:</p>
+<ul>
+ <li><em>uri</em> — The URI for the content to retrieve. </li>
+ <li><em>projection</em> — A list of which columns to return. Passing
+<code>null</code> will return all columns, which is inefficient. </li>
+ <li><em>selection</em> — A filter declaring which rows to return,
+formatted as an SQL WHERE clause (excluding the WHERE itself). Passing
+<code>null</code> will return all rows for the given URI. </li>
+ <li><em>selectionArgs</em> — You may include ?s in the selection, which will
+be replaced by the values from <em>selectionArgs</em>, in the order that they appear in
+the selection. The values will be bound as Strings. </li>
+ <li><em>sortOrder</em> — How to order the rows, formatted as an SQL
+ORDER BY clause (excluding the ORDER BY itself). Passing <code>null</code> will
+use the default sort order, which may be unordered.</li>
+</ul>
+<p>For example:</p>
+<pre>
+ // If non-null, this is the current filter the user has provided.
+String mCurFilter;
+...
+public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ // This is called when a new Loader needs to be created. This
+ // sample only has one Loader, so we don't care about the ID.
+ // First, pick the base URI to use depending on whether we are
+ // currently filtering.
+ Uri baseUri;
+ if (mCurFilter != null) {
+ baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
+ Uri.encode(mCurFilter));
+ } else {
+ baseUri = Contacts.CONTENT_URI;
+ }
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ + Contacts.DISPLAY_NAME + " != '' ))";
+ return new CursorLoader(getActivity(), baseUri,
+ CONTACTS_SUMMARY_PROJECTION, select, null,
+ Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
+}</pre>
+<h4 id="onLoadFinished">onLoadFinished</h4>
+
+<p>This method is called when a previously created loader has finished its load.
+This method is guaranteed to be called prior to the release of the last data
+that was supplied for this loader. At this point you should remove all use of
+the old data (since it will be released soon), but should not do your own
+release of the data since its loader owns it and will take care of that.</p>
+
+
+<p>The loader will release the data once it knows the application is no longer
+using it. For example, if the data is a cursor from a {@link
+android.content.CursorLoader}, you should not call {@link
+android.database.Cursor#close close()} on it yourself. If the cursor is being
+placed in a {@link android.widget.CursorAdapter}, you should use the {@link
+android.widget.SimpleCursorAdapter#swapCursor swapCursor()} method so that the
+old {@link android.database.Cursor} is not closed. For example:</p>
+
+<pre>
+// This is the Adapter being used to display the list's data.<br
+/>SimpleCursorAdapter mAdapter;
+...
+
+public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ mAdapter.swapCursor(data);
+}</pre>
+
+<h4 id="onLoaderReset">onLoaderReset</h4>
+
+<p>This method is called when a previously created loader is being reset, thus
+making its data unavailable. This callback lets you find out when the data is
+about to be released so you can remove your reference to it. </p>
+<p>This implementation calls
+{@link android.widget.SimpleCursorAdapter#swapCursor swapCursor()}
+with a value of <code>null</code>:</p>
+
+<pre>
+// This is the Adapter being used to display the list's data.
+SimpleCursorAdapter mAdapter;
+...
+
+public void onLoaderReset(Loader<Cursor> loader) {
+ // This is called when the last Cursor provided to onLoadFinished()
+ // above is about to be closed. We need to make sure we are no
+ // longer using it.
+ mAdapter.swapCursor(null);
+}</pre>
+
+
+<h2 id="example">Example</h2>
+
+<p>As an example, here is the full implementation of a {@link
+android.app.Fragment} that displays a {@link android.widget.ListView} containing
+the results of a query against the contacts content provider. It uses a {@link
+android.content.CursorLoader} to manage the query on the provider.</p>
+
+<p>For an application to access a user's contacts, as shown in this example, its
+manifest must include the permission
+{@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS}.</p>
+
+<pre>
+public static class CursorLoaderListFragment extends ListFragment
+ implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {
+
+ // This is the Adapter being used to display the list's data.
+ SimpleCursorAdapter mAdapter;
+
+ // If non-null, this is the current filter the user has provided.
+ String mCurFilter;
+
+ @Override public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ // Give some text to display if there is no data. In a real
+ // application this would come from a resource.
+ setEmptyText("No phone numbers");
+
+ // We have a menu item to show in action bar.
+ setHasOptionsMenu(true);
+
+ // Create an empty adapter we will use to display the loaded data.
+ mAdapter = new SimpleCursorAdapter(getActivity(),
+ android.R.layout.simple_list_item_2, null,
+ new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
+ new int[] { android.R.id.text1, android.R.id.text2 }, 0);
+ setListAdapter(mAdapter);
+
+ // Prepare the loader. Either re-connect with an existing one,
+ // or start a new one.
+ getLoaderManager().initLoader(0, null, this);
+ }
+
+ @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ // Place an action bar item for searching.
+ MenuItem item = menu.add("Search");
+ item.setIcon(android.R.drawable.ic_menu_search);
+ item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ SearchView sv = new SearchView(getActivity());
+ sv.setOnQueryTextListener(this);
+ item.setActionView(sv);
+ }
+
+ public boolean onQueryTextChange(String newText) {
+ // Called when the action bar search text has changed. Update
+ // the search filter, and restart the loader to do a new query
+ // with this filter.
+ mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+ getLoaderManager().restartLoader(0, null, this);
+ return true;
+ }
+
+ @Override public boolean onQueryTextSubmit(String query) {
+ // Don't care about this.
+ return true;
+ }
+
+ @Override public void onListItemClick(ListView l, View v, int position, long id) {
+ // Insert desired behavior here.
+ Log.i("FragmentComplexList", "Item clicked: " + id);
+ }
+
+ // These are the Contacts rows that we will retrieve.
+ static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME,
+ Contacts.CONTACT_STATUS,
+ Contacts.CONTACT_PRESENCE,
+ Contacts.PHOTO_ID,
+ Contacts.LOOKUP_KEY,
+ };
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ // This is called when a new Loader needs to be created. This
+ // sample only has one Loader, so we don't care about the ID.
+ // First, pick the base URI to use depending on whether we are
+ // currently filtering.
+ Uri baseUri;
+ if (mCurFilter != null) {
+ baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
+ Uri.encode(mCurFilter));
+ } else {
+ baseUri = Contacts.CONTENT_URI;
+ }
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ + Contacts.DISPLAY_NAME + " != '' ))";
+ return new CursorLoader(getActivity(), baseUri,
+ CONTACTS_SUMMARY_PROJECTION, select, null,
+ Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ mAdapter.swapCursor(data);
+ }
+
+ public void onLoaderReset(Loader<Cursor> loader) {
+ // This is called when the last Cursor provided to onLoadFinished()
+ // above is about to be closed. We need to make sure we are no
+ // longer using it.
+ mAdapter.swapCursor(null);
+ }
+}</pre>
+<h3 id="more_examples">More Examples</h3>
+
+<p>There are a few different samples in <strong>ApiDemos</strong> that
+illustrate how to use loaders:</p>
+<ul>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentCursorLoader.html"> FragmentCursorLoader</a> — A complete version of the
+snippet shown above.</li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> — An example of how to use throttling to
+reduce the number of queries a content provider does then its data changes.</li>
+</ul>
+
+<p>For information on downloading and installing the SDK samples, see <a
+href="http://developer.android.com/resources/samples/get.html"> Getting the
+Samples</a>. </p>
+
diff --git a/docs/html/guide/topics/ui/drag-drop.jd b/docs/html/guide/topics/ui/drag-drop.jd
new file mode 100644
index 0000000..46ccdf8
--- /dev/null
+++ b/docs/html/guide/topics/ui/drag-drop.jd
@@ -0,0 +1,995 @@
+page.title=Dragging and Dropping
+@jd:body
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>Quickview</h2>
+ <ul>
+ <li>
+ Allow users to move data within your Activity layout using graphical gestures.
+ </li>
+ <li>
+ Supports operations besides data movement.
+ </li>
+ <li>
+ Only works within a single application.
+ </li>
+ <li>
+ Requires API 11.
+ </li>
+ </ul>
+ <h2>In this document</h2>
+ <ol>
+ <li>
+ <a href="#AboutDragging">Overview</a>
+ <ol>
+ <li>
+ <a href="#DragDropLifecycle">The drag/drop process</a>
+ </li>
+ <li>
+ <a href="#AboutDragListeners">The drag event listener and callback method</a>
+ </li>
+ <li>
+ <a href="#AboutDragEvent">Drag events</a>
+ </li>
+ <li>
+ <a href="#AboutDragShadowBuilder">
+ The drag shadow</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>
+ <ol>
+ <li>
+ <a href="#StartDrag">Starting a drag</a>
+ </li>
+ <li>
+ <a href="#HandleStart">Responding to a drag start</a>
+ </li>
+ <li>
+ <a href="#HandleDuring">Handling events during the drag</a>
+ </li>
+ <li>
+ <a href="#HandleDrop">Responding to a drop</a>
+ </li>
+ <li>
+ <a href="#HandleEnd">Responding to a drag end</a>
+ </li>
+ <li>
+ <a href="#RespondEventSample">Responding to drag events: an example</a>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ <h2>Key classes</h2>
+ <ol>
+ <li>
+ {@link android.view.View View}
+ </li>
+ <li>
+ {@link android.view.View.OnLongClickListener OnLongClickListener}
+ </li>
+ <li>
+ {@link android.view.View.OnDragListener OnDragListener}
+ </li>
+ <li>
+ {@link android.view.DragEvent DragEvent}
+ </li>
+ <li>
+ {@link android.view.View.DragShadowBuilder DragShadowBuilder}
+ </li>
+ <li>
+ {@link android.content.ClipData ClipData}
+ </li>
+ <li>
+ {@link android.content.ClipDescription ClipDescription}
+ </li>
+ </ol>
+ <h2>Related Samples</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/HoneycombGallery/index.html">
+ Honeycomb Gallery</a>.
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">
+DragAndDropDemo.java</a> and
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DraggableDot.html">
+DraggableDot.java</a> in <a href="{@docRoot}resources/samples/ApiDemos/index.html">Api Demos</a>.
+ </li>
+ </ol>
+ <h2>See also</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/ui/ui-events.html">Handling UI Events</a>
+ </li>
+ </ol>
+ </div>
+</div>
+<p>
+ With the Android drag/drop framework, you can allow your users to move data
+ from one View to another View in the current layout using a graphical drag and drop gesture.
+ The framework includes a drag event class, drag listeners, and helper methods and classes.
+</p>
+<p>
+ Although the framework is primarily designed for data movement, you can use
+ it for other UI actions. For example, you could create an app that mixes colors when the user
+ drags a color icon over another icon. The rest of this topic, however, describes the
+ framework in terms of data movement.
+</p>
+<h2 id="AboutDragging">Overview</h2>
+<p>
+ A drag and drop operation starts when the user makes some gesture that you recognize as a
+ signal to start dragging data. In response, your application tells the system that the drag is
+ starting. The system calls back to your application to get a representation of the data
+ being dragged. As the user's finger moves this representation (a "drag shadow")
+ over the current layout, the system sends drag events to the drag event listener objects and
+ drag event callback methods associated with the {@link android.view.View} objects in the layout.
+ Once the user releases the drag shadow, the system ends the drag operation.
+</p>
+<p>
+ You create a drag event listener object ("listeners") from a class that implements
+ {@link android.view.View.OnDragListener}. You set the drag event listener object for a View
+ with the View object's
+ {@link android.view.View#setOnDragListener(View.OnDragListener) setOnDragListener()} method.
+ Each View object also has a {@link android.view.View#onDragEvent(DragEvent) onDragEvent()}
+ callback method. Both of these are described in more detail in the section
+ <a href="#AboutDragListeners">The drag event listener and callback method</a>.
+</p>
+<p class="note">
+ <strong>Note</strong>: For the sake of simplicity, the following sections refer to the routine
+ that receives drag events as the "drag event listener", even though it may actually
+ be a callback method.
+</p>
+<p>
+ When you start a drag, you include both the data you are moving and metadata describing this
+ data as part of the call to the system. During the drag, the system sends drag events to the
+ drag event listeners or callback methods of each View in the layout. The listeners or callback
+ methods can use the metadata to decide if they want to accept the data when it is dropped.
+ If the user drops the data over a View object, and that View object's listener or callback
+ method has previously told the system that it wants to accept the drop, then the system sends
+ the data to the listener or callback method in a drag event.
+</p>
+<p>
+ Your application tells the system to start a drag by calling the
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
+ method. This tells the system to start sending drag events. The method also sends the data that
+ you are dragging.
+</p>
+<p>
+ You can call
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
+ for any attached View in the current layout. The system only uses the View object to get access
+ to global settings in your layout.
+</p>
+<p>
+ Once your application calls
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()},
+ the rest of the process uses events that the system sends to the View objects in your current
+ layout.
+</p>
+<h3 id="DragDropLifecycle">The drag/drop process</h3>
+<p>
+ There are basically four steps or states in the drag and drop process:
+</p>
+<dl>
+ <dt>
+ <em>Started</em>
+ </dt>
+ <dd>
+ In response to the user's gesture to begin a drag, your application calls
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
+ to tell the system to start a drag. The arguments
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
+ provide the data to be dragged, metadata for this data, and a callback for drawing the
+ drag shadow.
+ <p>
+ The system first responds by calling back to your application to get a drag shadow. It
+ then displays the drag shadow on the device.
+ </p>
+ <p>
+ Next, the system sends a drag event with action type
+ {@link android.view.DragEvent#ACTION_DRAG_STARTED} to the drag event listeners for
+ all the View objects in the current layout. To continue to receive drag events,
+ including a possible drop event, a drag event listener must return <code>true</code>.
+ This registers the listener with the system. Only registered listeners continue to
+ receive drag events. At this point, listeners can also change the appearance of their
+ View object to show that the listener can accept a drop event.
+ </p>
+ <p>
+ If the drag event listener returns <code>false</code>, then it will not receive drag
+ events for the current operation until the system sends a drag event with action type
+ {@link android.view.DragEvent#ACTION_DRAG_ENDED}. By sending <code>false</code>, the
+ listener tells the system that it is not interested in the drag operation and
+ does not want to accept the dragged data.
+ </p>
+ </dd>
+ <dt>
+ <em>Continuing</em>
+ </dt>
+ <dd>
+ The user continues the drag. As the drag shadow intersects the bounding box of a View
+ object, the system sends one or more drag events to the View object's drag event
+ listener (if it is registered to receive events). The listener may choose to
+ alter its View object's appearance in response to the event. For example, if the event
+ indicates that the drag shadow has entered the bounding box of the View
+ (action type {@link android.view.DragEvent#ACTION_DRAG_ENTERED}), the listener
+ can react by highlighting its View.
+ </dd>
+ <dt>
+ <em>Dropped</em>
+ </dt>
+ <dd>
+ The user releases the drag shadow within the bounding box of a View that can accept the
+ data. The system sends the View object's listener a drag event with action type
+ {@link android.view.DragEvent#ACTION_DROP}. The drag event contains the data that was
+ passed to the system in the call to
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
+ that started the operation. The listener is expected to return boolean <code>true</code> to
+ the system if code for accepting the drop succeeds.
+ <p>
+ Note that this step only occurs if the user drops the drag shadow within the bounding
+ box of a View whose listener is registered to receive drag events. If the user releases
+ the drag shadow in any other situation, no {@link android.view.DragEvent#ACTION_DROP}
+ drag event is sent.
+ </p>
+ </dd>
+ <dt>
+ <em>Ended</em>
+ </dt>
+ <dd>
+ After the user releases the drag shadow, and after the system sends out (if necessary)
+ a drag event with action type {@link android.view.DragEvent#ACTION_DROP}, the system sends
+ out a drag event with action type {@link android.view.DragEvent#ACTION_DRAG_ENDED} to
+ indicate that the drag operation is over. This is done regardless of where the user released
+ the drag shadow. The event is sent to every listener that is registered to receive drag
+ events, even if the listener received the {@link android.view.DragEvent#ACTION_DROP} event.
+ </dd>
+</dl>
+<p>
+ Each of these four steps is described in more detail in the section
+ <a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>.
+</p>
+<h3 id="AboutDragListeners">The drag event listener and callback method</h3>
+<p>
+ A View receives drag events with either a drag event listener that implements
+ {@link android.view.View.OnDragListener} or with its
+ {@link android.view.View#onDragEvent(DragEvent)} callback method.
+ When the system calls the method or listener, it passes to them
+ a {@link android.view.DragEvent} object.
+</p>
+<p>
+ You will probably want to use the listener in most cases. When you design UIs, you usually
+ don't subclass View classes, but using the callback method forces you to do this in order to
+ override the method. In comparison, you can implement one listener class and then use it with
+ several different View objects. You can also implement it as an anonymous inline class. To
+ set the listener for a View object, call
+{@link android.view.View#setOnDragListener(android.view.View.OnDragListener) setOnDragListener()}.
+</p>
+<p>
+ You can have both a listener and a callback method for View object. If this occurs,
+ the system first calls the listener. The system doesn't call the callback method unless the
+ listener returns <code>false</code>.
+</p>
+<p>
+ The combination of the {@link android.view.View#onDragEvent(DragEvent)} method and
+ {@link android.view.View.OnDragListener} is analogous to the combination
+ of the {@link android.view.View#onTouchEvent(MotionEvent) onTouchEvent()} and
+ {@link android.view.View.OnTouchListener} used with touch events.
+</p>
+<h3 id="AboutDragEvent">Drag events</h3>
+<p>
+ The system sends out a drag event in the form of a {@link android.view.DragEvent} object. The
+ object contains an action type that tells the listener what is happening in the drag/drop
+ process. The object contains other data, depending on the action type.
+</p>
+<p>
+ To get the action type, a listener calls {@link android.view.DragEvent#getAction()}. There
+ are six possible values, defined by constants in the {@link android.view.DragEvent} class. These
+ are listed in <a href="table1">table 1</a>.
+</p>
+<p>
+ The {@link android.view.DragEvent} object also contains the data that your application provided
+ to the system in the call to
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}.
+ Some of the data is valid only for certain action types. The data that is valid for each action
+ type is summarized in <a href="table2">table 2</a>. It is also described in detail with
+ the event for which it is valid in the section
+ <a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>.
+</p>
+<p class="table-caption" id="table1">
+ <strong>Table 1.</strong> DragEvent action types
+</p>
+<table>
+ <tr>
+ <th scope="col">getAction() value</th>
+ <th scope="col">Meaning</th>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_STARTED}</td>
+ <td>
+ A View object's drag event listener receives this event action type just after the
+ application calls
+{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()} and
+ gets a drag shadow.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_ENTERED}</td>
+ <td>
+ A View object's drag event listener receives this event action type when the drag shadow
+ has just entered the bounding box of the View. This is the first event action type the
+ listener receives when the drag shadow enters the bounding box. If the listener wants to
+ continue receiving drag events for this operation, it must return boolean
+ <code>true</code> to the system.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_LOCATION}</td>
+ <td>
+ A View object's drag event listener receives this event action type after it receives a
+ {@link android.view.DragEvent#ACTION_DRAG_ENTERED} event while the drag shadow is
+ still within the bounding box of the View.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_EXITED}</td>
+ <td>
+ A View object's drag event listener receives this event action type after it receives a
+ {@link android.view.DragEvent#ACTION_DRAG_ENTERED} and at least one
+ {@link android.view.DragEvent#ACTION_DRAG_LOCATION} event, and after the user has moved
+ the drag shadow outside the bounding box of the View.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DROP}</td>
+ <td>
+ A View object's drag event listener receives this event action type when the user
+ releases the drag shadow over the View object. This action type is only sent to a View
+ object's listener if the listener returned boolean <code>true</code> in response to the
+ {@link android.view.DragEvent#ACTION_DRAG_STARTED} drag event. This action type is not
+ sent if the user releases the drag shadow on a View whose listener is not registered,
+ or if the user releases the drag shadow on anything that is not part of the current
+ layout.
+ <p>
+ The listener is expected to return boolean <code>true</code> if it successfully
+ processes the drop. Otherwise, it should return <code>false</code>.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_ENDED}</td>
+ <td>
+ A View object's drag event listener receives this event action type
+ when the system is ending the drag operation. This action type is not necessarily
+ preceded by an {@link android.view.DragEvent#ACTION_DROP} event. If the system sent
+ a {@link android.view.DragEvent#ACTION_DROP}, receiving the
+ {@link android.view.DragEvent#ACTION_DRAG_ENDED} action type does not imply that the
+ drop operation succeeded. The listener must call
+ {@link android.view.DragEvent#getResult()} to get the value that was
+ returned in response to {@link android.view.DragEvent#ACTION_DROP}. If an
+ {@link android.view.DragEvent#ACTION_DROP} event was not sent, then
+ {@link android.view.DragEvent#getResult()} returns <code>false</code>.
+ </td>
+ </tr>
+</table>
+<p class="table-caption" id="table2">
+ <strong>Table 2.</strong> Valid DragEvent data by action type</p>
+<table>
+ <tr>
+ <th scope="col">{@link android.view.DragEvent#getAction()} value</th>
+ <th scope="col">{@link android.view.DragEvent#getClipDescription()} value</th>
+ <th scope="col">{@link android.view.DragEvent#getLocalState()} value</th>
+ <th scope="col">{@link android.view.DragEvent#getX()} value</th>
+ <th scope="col">{@link android.view.DragEvent#getY()} value</th>
+ <th scope="col">{@link android.view.DragEvent#getClipData()} value</th>
+ <th scope="col">{@link android.view.DragEvent#getResult()} value</th>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_STARTED}</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_ENTERED}</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_LOCATION}</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_EXITED}</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DROP}</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;"> </td>
+ </tr>
+ <tr>
+ <td>{@link android.view.DragEvent#ACTION_DRAG_ENDED}</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;">X</td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;"> </td>
+ <td style="text-align: center;">X</td>
+ </tr>
+</table>
+<p>
+ The {@link android.view.DragEvent#getAction()},
+ {@link android.view.DragEvent#describeContents()},
+ {@link android.view.DragEvent#writeToParcel(Parcel,int) writeToParcel()}, and
+ {@link android.view.DragEvent#toString()} methods always return valid data.
+</p>
+<p>
+ If a method does not contain valid data for a particular action type, it returns either
+ <code>null</code> or 0, depending on its result type.
+</p>
+<h3 id="AboutDragShadowBuilder">
+ The drag shadow
+</h3>
+<p>
+ During a drag and drop operation, the system displays a image that the user drags.
+ For data movement, this image represents the data being dragged. For other operations, the
+ image represents some aspect of the drag operation.
+</p>
+<p>
+ The image is called a drag shadow. You create it with methods you declare for a
+ {@link android.view.View.DragShadowBuilder} object, and then pass it to the system when you
+ start a drag using
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}.
+ As part of its response to
+ {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()},
+ the system invokes the callback methods you've defined in
+ {@link android.view.View.DragShadowBuilder} to obtain a drag shadow.
+</p>
+<p>
+ The {@link android.view.View.DragShadowBuilder} class has two constructors:
+</p>
+ <dl>
+ <dt>{@link android.view.View.DragShadowBuilder#View.DragShadowBuilder(View)}</dt>
+ <dd>
+ This constructor accepts any of your application's
+ {@link android.view.View} objects. The constructor stores the View object
+ in the {@link android.view.View.DragShadowBuilder} object, so during
+ the callback you can access it as you construct your drag shadow.
+ It doesn't have to be associated with the View (if any) that the user
+ selected to start the drag operation.
+ <p>
+ If you use this constructor, you don't have to extend
+ {@link android.view.View.DragShadowBuilder} or override its methods. By default,
+ you will get a drag shadow that has the same appearance as the View you pass as an
+ argument, centered under the location where the user is touching the screen.
+ </p>
+ </dd>
+ <dt>{@link android.view.View.DragShadowBuilder#View.DragShadowBuilder()}</dt>
+ <dd>
+ If you use this constructor, no View object is available in the
+ {@link android.view.View.DragShadowBuilder} object (the field is set to <code>null</code>).
+ If you use this constructor, and you don't extend
+ {@link android.view.View.DragShadowBuilder} or override its methods,
+ you will get an invisible drag shadow.
+ The system does <em>not</em> give an error.
+ </dd>
+</dl>
+<p>
+ The {@link android.view.View.DragShadowBuilder} class has two methods:
+</p>
+<dl>
+ <dt>
+{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
+ </dt>
+ <dd>
+ The system calls this method immediately after you call
+{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}. Use it
+ to send to the system the dimensions and touch point of the drag shadow. The method has two
+ arguments:
+ <dl>
+ <dt><em>dimensions</em></dt>
+ <dd>
+ A {@link android.graphics.Point} object. The drag shadow width goes in
+ {@link android.graphics.Point#x} and its height goes in
+ {@link android.graphics.Point#y}.
+ </dd>
+ <dt><em>touch_point</em></dt>
+ <dd>
+ A {@link android.graphics.Point} object. The touch point is the location within the
+ drag shadow that should be under the user's finger during the drag. Its X
+ position goes in {@link android.graphics.Point#x} and its Y position goes in
+ {@link android.graphics.Point#y}
+ </dd>
+ </dl>
+ </dd>
+ <dt>
+ {@link android.view.View.DragShadowBuilder#onDrawShadow(Canvas) onDrawShadow()}
+ </dt>
+ <dd>
+ Immediately after the call to
+{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
+ the system calls
+ {@link android.view.View.DragShadowBuilder#onDrawShadow(Canvas) onDrawShadow()} to get the
+ drag shadow itself. The method has a single argument, a {@link android.graphics.Canvas}
+ object that the system constructs from the parameters you provide in
+{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
+ Use it to draw the drag shadow in the provided {@link android.graphics.Canvas} object.
+ </dd>
+</dl>
+<p>
+ To improve performance, you should keep the size of the drag shadow small. For a single item,
+ you may want to use a icon. For a multiple selection, you may want to use icons in a stack
+ rather than full images spread out over the screen.
+</p>
+<h2 id="DesignDragOperation">Designing a Drag and Drop Operation</h2>
+<p>
+ This section shows step-by-step how to start a drag, how to respond to events during
+ the drag, how respond to a drop event, and how to end the drag and drop operation.
+</p>
+<h3 id="StartDrag">Starting a drag</h3>
+<p>
+ The user starts a drag with a drag gesture, usually a long press, on a View object.
+ In response, you should do the following:
+</p>
+<ol>
+ <li>
+ As necessary, create a {@link android.content.ClipData} and
+ {@link android.content.ClipData.Item} for the data being moved. As part of the
+ ClipData object, supply metadata that is stored in a {@link android.content.ClipDescription}
+ object within the ClipData. For a drag and drop operation that does not represent data
+ movement, you may want to use <code>null</code> instead of an actual object.
+ <p>
+ For example, this code snippet shows how to respond to a long press on a ImageView
+ by creating a ClipData object that contains the tag or label of an
+ ImageView. Following this snippet, the next snippet shows how to override the methods in
+ {@link android.view.View.DragShadowBuilder}:
+ </p>
+<pre>
+// Create a string for the ImageView label
+private static final String IMAGEVIEW_TAG = "icon bitmap"
+
+// Creates a new ImageView
+ImageView imageView = new ImageView(this);
+
+// Sets the bitmap for the ImageView from an icon bit map (defined elsewhere)
+imageView.setImageBitmap(mIconBitmap);
+
+// Sets the tag
+imageView.setTag(IMAGEVIEW_TAG);
+
+ ...
+
+// Sets a long click listener for the ImageView using an anonymous listener object that
+// implements the OnLongClickListener interface
+imageView.setOnLongClickListener(new View.OnLongClickListener() {
+
+ // Defines the one method for the interface, which is called when the View is long-clicked
+ public boolean onLongClick(View v) {
+
+ // Create a new ClipData.
+ // This is done in two steps to provide clarity. The convenience method
+ // ClipData.newPlainText() can create a plain text ClipData in one step.
+
+ // Create a new ClipData.Item from the ImageView object's tag
+ ClipData.Item item = new ClipData.Item(v.getTag());
+
+ // Create a new ClipData using the tag as a label, the plain text MIME type, and
+ // the already-created item. This will create a new ClipDescription object within the
+ // ClipData, and set its MIME type entry to "text/plain"
+ ClipData dragData = new ClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item);
+
+ // Instantiates the drag shadow builder.
+ View.DrawShadowBuilder myShadow = new MyDragShadowBuilder(imageView);
+
+ // Starts the drag
+
+ v.startDrag(dragData, // the data to be dragged
+ myShadow, // the drag shadow builder
+ null, // no need to use local data
+ 0 // flags (not currently used, set to 0)
+ );
+
+ }
+}
+</pre>
+ </li>
+ <li>
+ The following code snippet defines {@code myDragShadowBuilder}
+ It creates a drag shadow for dragging a TextView as a small gray rectangle:
+<pre>
+ private static class MyDragShadowBuilder extends View.DragShadowBuilder {
+
+ // The drag shadow image, defined as a drawable thing
+ private static Drawable shadow;
+
+ // Defines the constructor for myDragShadowBuilder
+ public MyDragShadowBuilder(View v) {
+
+ // Stores the View parameter passed to myDragShadowBuilder.
+ super(v);
+
+ // Creates a draggable image that will fill the Canvas provided by the system.
+ shadow = new ColorDrawable(Color.LTGRAY);
+ }
+
+ // Defines a callback that sends the drag shadow dimensions and touch point back to the
+ // system.
+ @Override
+ public void onProvideShadowMetrics (Point size, Point touch)
+ // Defines local variables
+ private int width, height;
+
+ // Sets the width of the shadow to half the width of the original View
+ width = getView().getWidth() / 2;
+
+ // Sets the height of the shadow to half the height of the original View
+ height = getView().getHeight() / 2;
+
+ // The drag shadow is a ColorDrawable. This sets its dimensions to be the same as the
+ // Canvas that the system will provide. As a result, the drag shadow will fill the
+ // Canvas.
+ shadow.setBounds(0, 0, width, height);
+
+ // Sets the size parameter's width and height values. These get back to the system
+ // through the size parameter.
+ size.set(width, height);
+
+ // Sets the touch point's position to be in the middle of the drag shadow
+ touch.set(width / 2, height / 2);
+ }
+
+ // Defines a callback that draws the drag shadow in a Canvas that the system constructs
+ // from the dimensions passed in onProvideShadowMetrics().
+ @Override
+ public void onDrawShadow(Canvas canvas) {
+
+ // Draws the ColorDrawable in the Canvas passed in from the system.
+ shadow.draw(canvas);
+ }
+ }
+</pre>
+ <p class="note">
+ <strong>Note:</strong> Remember that you don't have to extend
+ {@link android.view.View.DragShadowBuilder}. The constructor
+ {@link android.view.View.DragShadowBuilder#View.DragShadowBuilder(View)} creates a
+ default drag shadow that's the same size as the View argument passed to it, with the
+ touch point centered in the drag shadow.
+ </p>
+ </li>
+</ol>
+<h3 id="HandleStart">Responding to a drag start</h3>
+<p>
+ During the drag operation, the system dispatches drag events to the drag event listeners
+ of the View objects in the current layout. The listeners should react
+ by calling {@link android.view.DragEvent#getAction()} to get the action type.
+ At the start of a drag, this methods returns {@link android.view.DragEvent#ACTION_DRAG_STARTED}.
+</p>
+<p>
+ In response to an event with the action type {@link android.view.DragEvent#ACTION_DRAG_STARTED},
+ a listener should do the following:
+</p>
+<ol>
+ <li>
+ Call {@link android.view.DragEvent#getClipDescription()} to get the
+ {@link android.content.ClipDescription}. Use the MIME type methods in
+ {@link android.content.ClipDescription} to see if the listener can accept the data being
+ dragged.
+ <p>
+ If the drag and drop operation does not represent data movement, this may not be
+ necessary.
+ </p>
+ </li>
+ <li>
+ If the listener can accept a drop, it should return <code>true</code>. This tells
+ the system to continue to send drag events to the listener.
+ If it can't accept a drop, it should return <code>false</code>, and the system
+ will stop sending drag events until it sends out
+ {@link android.view.DragEvent#ACTION_DRAG_ENDED}.
+ </li>
+</ol>
+<p>
+ Note that for an {@link android.view.DragEvent#ACTION_DRAG_STARTED} event, these
+ the following {@link android.view.DragEvent} methods are not valid:
+ {@link android.view.DragEvent#getClipData()}, {@link android.view.DragEvent#getX()},
+ {@link android.view.DragEvent#getY()}, and {@link android.view.DragEvent#getResult()}.
+</p>
+<h3 id="HandleDuring">Handling events during the drag</h3>
+<p>
+ During the drag, listeners that returned <code>true</code> in response to
+ the {@link android.view.DragEvent#ACTION_DRAG_STARTED} drag event continue to receive drag
+ events. The types of drag events a listener receives during the drag depend on the location of
+ the drag shadow and the visibility of the listener's View.
+</p>
+<p>
+ During the drag, listeners primarily use drag events to decide if they should change the
+ appearance of their View.
+</p>
+<p>
+ During the drag, {@link android.view.DragEvent#getAction()} returns one of three
+ values:
+</p>
+<ul>
+ <li>
+ {@link android.view.DragEvent#ACTION_DRAG_ENTERED}:
+ The listener receives this when the touch point
+ (the point on the screen underneath the user's finger) has entered the bounding box of the
+ listener's View.
+ </li>
+ <li>
+ {@link android.view.DragEvent#ACTION_DRAG_LOCATION}: Once the listener receives an
+ {@link android.view.DragEvent#ACTION_DRAG_ENTERED} event, and before it receives an
+ A{@link android.view.DragEvent#ACTION_DRAG_EXITED} event, it receives a new
+ {@link android.view.DragEvent#ACTION_DRAG_LOCATION} event every time the touch point moves.
+ The {@link android.view.DragEvent#getX()} and {@link android.view.DragEvent#getY()} methods
+ return the the X and Y coordinates of the touch point.
+ </li>
+ <li>
+ {@link android.view.DragEvent#ACTION_DRAG_EXITED}: This event is sent to a listener that
+ previously received {@link android.view.DragEvent#ACTION_DRAG_ENTERED}, after
+ the drag shadow is no longer within the bounding box of the listener's View.
+ </li>
+</ul>
+<p>
+ The listener does not need to react to any of these action types. If the listener returns a
+ value to the system, it is ignored. Here are some guidelines for responding to each of
+ these action types:
+</p>
+<ul>
+ <li>
+ In response to {@link android.view.DragEvent#ACTION_DRAG_ENTERED} or
+ {@link android.view.DragEvent#ACTION_DRAG_LOCATION}, the listener can change the appearance
+ of the View to indicate that it is about to receive a drop.
+ </li>
+ <li>
+ An event with the action type {@link android.view.DragEvent#ACTION_DRAG_LOCATION} contains
+ valid data for {@link android.view.DragEvent#getX()} and
+ {@link android.view.DragEvent#getY()}, corresponding to the location of the touch point.
+ The listener may want to use this information to alter the appearance of that part of the
+ View that is at the touch point. The listener can also use this information
+ to determine the exact position where the user is going to drop the drag shadow.
+ </li>
+ <li>
+ In response to {@link android.view.DragEvent#ACTION_DRAG_EXITED}, the listener should reset
+ any appearance changes it applied in response to
+ {@link android.view.DragEvent#ACTION_DRAG_ENTERED} or
+ {@link android.view.DragEvent#ACTION_DRAG_LOCATION}. This indicates to the user that
+ the View is no longer an imminent drop target.
+ </li>
+</ul>
+<h3 id="HandleDrop">Responding to a drop</h3>
+<p>
+ When the user releases the drag shadow on a View in the application, and that View previously
+ reported that it could accept the content being dragged, the system dispatches a drag event
+ to that View with the action type {@link android.view.DragEvent#ACTION_DROP}. The listener
+ should do the following:
+</p>
+<ol>
+ <li>
+ Call {@link android.view.DragEvent#getClipData()} to get the
+ {@link android.content.ClipData} object that was originally supplied in the call
+ to
+{@link android.view.View#startDrag(ClipData, View.DragShadowBuilder, Object, int) startDrag()}
+ and store it. If the drag and drop operation does not represent data movement,
+ this may not be necessary.
+ </li>
+ <li>
+ Return boolean <code>true</code> to indicate that the drop was processed successfully, or
+ boolean <code>false</code> if it was not. The returned value becomes the value returned by
+ {@link android.view.DragEvent#getResult()} for an
+ {@link android.view.DragEvent#ACTION_DRAG_ENDED} event.
+ <p>
+ Note that if the system does not send out an {@link android.view.DragEvent#ACTION_DROP}
+ event, the value of {@link android.view.DragEvent#getResult()} for an
+ {@link android.view.DragEvent#ACTION_DRAG_ENDED} event is <code>false</code>.
+ </p>
+ </li>
+</ol>
+<p>
+ For an {@link android.view.DragEvent#ACTION_DROP} event,
+ {@link android.view.DragEvent#getX()} and {@link android.view.DragEvent#getY()}
+ return the X and Y position of the drag point at the moment of the drop, using the coordinate
+ system of the View that received the drop.
+</p>
+<p>
+ The system does allow the user to release the drag shadow on a View whose listener is not
+ receiving drag events. It will also allow the user to release the drag shadow
+ on empty regions of the application's UI, or on areas outside of your application.
+ In all of these cases, the system does not send an event with action type
+ {@link android.view.DragEvent#ACTION_DROP}, although it does send out an
+ {@link android.view.DragEvent#ACTION_DRAG_ENDED} event.
+</p>
+<h3 id="HandleEnd">Responding to a drag end</h3>
+<p>
+ Immediately after the user releases the drag shadow, the system sends a
+ drag event to all of the drag event listeners in your application, with an action type of
+ {@link android.view.DragEvent#ACTION_DRAG_ENDED}. This indicates that the drag operation is
+ over.
+</p>
+<p>
+ Each listener should do the following:
+</p>
+<ol>
+ <li>
+ If listener changed its View object's appearance during the operation, it should reset the
+ View to its default appearance. This is a visual indication to the user that the operation
+ is over.
+ </li>
+ <li>
+ The listener can optionally call {@link android.view.DragEvent#getResult()} to find out more
+ about the operation. If a listener returned <code>true</code> in response to an event of
+ action type {@link android.view.DragEvent#ACTION_DROP}, then
+ {@link android.view.DragEvent#getResult()} will return boolean <code>true</code>. In all
+ other cases, {@link android.view.DragEvent#getResult()} returns boolean <code>false</code>,
+ including any case in which the system did not send out a
+ {@link android.view.DragEvent#ACTION_DROP} event.
+ </li>
+ <li>
+ The listener should return boolean <code>true</code> to the system.
+ </li>
+</ol>
+<p>
+</p>
+<h3 id="RespondEventSample">Responding to drag events: an example</h3>
+<p>
+ All drag events are initially received by your drag event method or listener. The following
+ code snippet is a simple example of reacting to drag events in a listener:
+</p>
+<pre>
+// Creates a new drag event listener
+mDragListen = new myDragEventListener();
+
+View imageView = new ImageView(this);
+
+// Sets the drag event listener for the View
+imageView.setOnDragListener(mDragListen);
+
+...
+
+protected class myDragEventListener implements View.OnDragEventListener {
+
+ // This is the method that the system calls when it dispatches a drag event to the
+ // listener.
+ public boolean onDrag(View v, DragEvent event) {
+
+ // Defines a variable to store the action type for the incoming event
+ final int action = event.getAction();
+
+ // Handles each of the expected events
+ switch(action) {
+
+ case DragEvent.ACTION_DRAG_STARTED:
+
+ // Determines if this View can accept the dragged data
+ if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
+
+ // As an example of what your application might do,
+ // applies a blue color tint to the View to indicate that it can accept
+ // data.
+ v.setColorFilter(Color.BLUE);
+
+ // Invalidate the view to force a redraw in the new tint
+ v.invalidate();
+
+ // returns true to indicate that the View can accept the dragged data.
+ return(true);
+
+ } else {
+
+ // Returns false. During the current drag and drop operation, this View will
+ // not receive events again until ACTION_DRAG_ENDED is sent.
+ return(false);
+
+ }
+ break;
+
+ case DragEvent.ACTION_DRAG_ENTERED: {
+
+ // Applies a green tint to the View. Return true; the return value is ignored.
+
+ v.setColorFilter(Color.GREEN);
+
+ // Invalidate the view to force a redraw in the new tint
+ v.invalidate();
+
+ return(true);
+
+ break;
+
+ case DragEvent.ACTION_DRAG_LOCATION:
+
+ // Ignore the event
+ return(true);
+
+ break;
+
+ case DragEvent.ACTION_DRAG_EXITED:
+
+ // Re-sets the color tint to blue. Returns true; the return value is ignored.
+ v.setColorFilter(Color.BLUE);
+
+ // Invalidate the view to force a redraw in the new tint
+ v.invalidate();
+
+ return(true);
+
+ break;
+
+ case DragEvent.ACTION_DROP:
+
+ // Gets the item containing the dragged data
+ ClipData.Item item = event.getClipData().getItemAt(0);
+
+ // Gets the text data from the item.
+ dragData = item.getText();
+
+ // Displays a message containing the dragged data.
+ Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG);
+
+ // Turns off any color tints
+ v.clearColorFilter();
+
+ // Invalidates the view to force a redraw
+ v.invalidate();
+
+ // Returns true. DragEvent.getResult() will return true.
+ return(true);
+
+ break;
+
+ case DragEvent.ACTION_DRAG_ENDED:
+
+ // Turns off any color tinting
+ v.clearColorFilter();
+
+ // Invalidates the view to force a redraw
+ v.invalidate();
+
+ // Does a getResult(), and displays what happened.
+ if (event.getResult()) {
+ Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG);
+
+ } else {
+ Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG);
+
+ };
+
+ // returns true; the value is ignored.
+ return(true);
+
+ break;
+
+ // An unknown action type was received.
+ default:
+ Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
+
+ break;
+ };
+ };
+};
+</pre>
\ No newline at end of file
diff --git a/docs/html/images/animation/animation-linear.png b/docs/html/images/animation/animation-linear.png
new file mode 100644
index 0000000..08bd9fc
--- /dev/null
+++ b/docs/html/images/animation/animation-linear.png
Binary files differ
diff --git a/docs/html/images/animation/animation-nonlinear.png b/docs/html/images/animation/animation-nonlinear.png
new file mode 100644
index 0000000..31c1712
--- /dev/null
+++ b/docs/html/images/animation/animation-nonlinear.png
Binary files differ
diff --git a/docs/html/images/animation/valueanimator.png b/docs/html/images/animation/valueanimator.png
new file mode 100644
index 0000000..6cc2a13
--- /dev/null
+++ b/docs/html/images/animation/valueanimator.png
Binary files differ
diff --git a/docs/html/images/ui/clipboard/copy_paste_framework.png b/docs/html/images/ui/clipboard/copy_paste_framework.png
new file mode 100755
index 0000000..57facaa
--- /dev/null
+++ b/docs/html/images/ui/clipboard/copy_paste_framework.png
Binary files differ
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 5a3145b..5839064 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -25,7 +25,8 @@
'search': 'Search',
'testing': 'Testing',
'ui': 'User Interface',
- 'web': 'Web Content'
+ 'web': 'Web Content',
+ 'widgets': 'App Widgets'
},
misc: {
'external': 'External',
@@ -345,17 +346,17 @@
///////////////////
{
- tags: ['sample'],
+ tags: ['sample', 'new'],
path: 'samples/AccelerometerPlay/index.html',
title: {
en: 'Accelerometer Play'
},
description: {
- en: ''
+ en: 'An example of using the accelerometer to integrate the device\'s acceleration to a position using the Verlet method. This is illustrated with a very simple particle system comprised of a few iron balls freely moving on an inclined wooden table. The inclination of the virtual table is controlled by the device\'s accelerometer.'
}
},
{
- tags: ['sample'],
+ tags: ['sample', 'new', 'accessibility'],
path: 'samples/AccessibilityService/index.html',
title: {
en: 'Accessibility Service'
@@ -565,6 +566,16 @@
}
},
{
+ tags: ['sample', 'new', 'newfeature', 'widgets'],
+ path: 'samples/StackWidget/index.html',
+ title: {
+ en: 'StackView Widget'
+ },
+ description: {
+ en: 'Demonstrates how to create a simple collection widget containing a StackView.'
+ }
+ },
+ {
tags: ['sample', 'newfeature'],
path: 'samples/TicTacToeLib/index.html',
title: {
@@ -585,7 +596,7 @@
}
},
{
- tags: ['sample', 'ui'],
+ tags: ['sample', 'ui', 'widgets'],
path: 'samples/Wiktionary/index.html',
title: {
en: 'Wiktionary'
@@ -595,7 +606,7 @@
}
},
{
- tags: ['sample', 'ui'],
+ tags: ['sample', 'ui', 'widgets'],
path: 'samples/WiktionarySimple/index.html',
title: {
en: 'Wiktionary (Simplified)'
@@ -605,6 +616,16 @@
}
},
{
+ tags: ['sample', 'widgets', 'newfeature', 'new'],
+ path: 'samples/WeatherListWidget/index.html',
+ title: {
+ en: 'Weather List Widget'
+ },
+ description: {
+ en: 'A more complex collection-widget example which uses a ContentProvider as its data source.'
+ }
+ },
+ {
tags: ['sample', 'layout'],
path: 'samples/XmlAdapters/index.html',
title: {
diff --git a/docs/html/resources/samples/images/StackWidget.png b/docs/html/resources/samples/images/StackWidget.png
new file mode 100644
index 0000000..f2f83a0
--- /dev/null
+++ b/docs/html/resources/samples/images/StackWidget.png
Binary files differ
diff --git a/docs/html/resources/samples/images/WeatherListWidget.png b/docs/html/resources/samples/images/WeatherListWidget.png
new file mode 100644
index 0000000..f0cbdaf
--- /dev/null
+++ b/docs/html/resources/samples/images/WeatherListWidget.png
Binary files differ
diff --git a/docs/html/resources/samples/index.jd b/docs/html/resources/samples/index.jd
index beecd67..acb80e82 100644
--- a/docs/html/resources/samples/index.jd
+++ b/docs/html/resources/samples/index.jd
@@ -1,138 +1,11 @@
page.title=List of Sample Apps
@jd:body
-<p>The list below provides a summary of the sample applications that are
-available with the Android SDK. Using the links on this page, you can view
-the source files of the sample applications in your browser. </p>
+<script type="text/javascript">
+ window.location = toRoot + "resources/browser.html?tag=sample";
+</script>
-<p>You can also download the source of these samples into your SDK, then
-modify and reuse it as you need. For more information, see <a
-href="{@docRoot}resources/samples/get.html">Getting the Samples</a>.</p>
-<!--
-<div class="special">
- <p>Some of the samples in this listing may not yet be available in the
- SDK. To ensure that you have the latest versions of the samples, you can
- <a href="{@docRoot}shareables/latest_samples.zip">download the samples pack</a>
- as a .zip archive.</p>
-</div>
--->
-<dl>
-
- <dt><a href="AccelerometerPlay/index.html">Accelerometer Play</a></dt>
- <dd>An example that demonstrates how to use accelerometer readings
- in an application.</dd>
-
- <dt><a href="AccessibilityService/index.html">Accessibility Service</a></dt>
- <dd>An example that demonstrates the use of accessibility APIs.</dd>
-
- <dt><a href="ApiDemos/index.html">API Demos</a></dt>
- <dd>A variety of small applications that demonstrate an extensive collection of
- framework topics.</dd>
-
- <dt><a href="BackupRestore/index.html">Backup and Restore</a></dt>
- <dd>A simple example that illustrates a few different ways for an application to
- implement support for the Android data backup and restore mechanism.</dd>
-
- <dt><a href="BluetoothChat/index.html">Bluetooth Chat</a></dt>
- <dd>An application for two-way text messaging over Bluetooth.</dd>
-
- <dt><a href="BusinessCard/index.html">BusinessCard</a></dt>
- <dd>An application that demonstrates how to launch the built-in contact
- picker from within an activity. This sample also uses reflection to ensure
- that the correct version of the contacts API is used, depending on which
- API level the application is running under.</dd>
-
- <dt><a href="ContactManager/index.html">Contact Manager</a></dt>
- <dd>An application that demonstrates how to query the system contacts provider
- using the <code>ContactsContract</code> API, as
- well as insert contacts into a specific account.</dd>
-
- <dt><a href="Home/index.html">Home</a></dt>
- <dd>A home screen replacement application.</dd>
-
- <dt><a href="JetBoy/index.html">JetBoy</a></dt>
- <dd>A game that demonstrates the SONiVOX JET interactive music technology,
- with {@link android.media.JetPlayer}.</dd>
-
- <dt><a href="CubeLiveWallpaper/index.html">Live Wallpaper</a></dt>
- <dd>An application that demonstrates how to create a live wallpaper and
- bundle it in an application that users can install on their devices.</dd>
-
- <dt><a href="LunarLander/index.html">Lunar Lander</a></dt>
- <dd>A classic Lunar Lander game.</dd>
-
- <dt><a href="MultiResolution/index.html">Multiple Resolutions</a></dt>
- <dd>A sample application that shows how to use resource directory qualifiers to
- provide different resources for different screen configurations.</dd>
-
- <dt><a href="NotePad/index.html">Note Pad</a></dt>
- <dd>An application for saving notes. Similar (but not identical) to the
- <a href="{@docRoot}resources/tutorials/notepad/index.html">Notepad tutorial</a>.</dd>
-
- <dt><a href="SampleSyncAdapter/index.html">SampleSyncAdapter</a></dt>
- <dd>Demonstrates how an application can communicate with a
-cloud-based service and synchronize its data with data stored locally in a
-content provider. The sample uses two related parts of the Android framework
-— the account manager and the synchronization manager (through a sync
-adapter).</dd>
-
- <dt><a href="SearchableDictionary/index.html">Searchable Dictionary</a></dt>
- <dd>A sample application that demonstrates Android's search framework,
- including how to provide search suggestions for Quick Search Box.</dd>
-
- <dt><a href="SipDemo/index.html">SIP Demo</a></dt>
- <dd>An application that demonstrates how to make an internet-based call using the SIP
- API.</dd>
-
- <dt><a href="Snake/index.html">Snake</a></dt>
- <dd>An implementation of the classic game "Snake."</dd>
-
- <dt><a href="SoftKeyboard/index.html">Soft Keyboard</a></dt>
- <dd>An example of writing an input method for a software keyboard.</dd>
-
- <dt><a href="Spinner/index.html">Spinner</a></dt>
- <dd>
- A simple application that serves as an application-under-test for the
- SpinnerTest sample application.
- </dd>
- <dt><a href="SpinnerTest/index.html">SpinnerTest</a></dt>
- <dd>
- An example test application that contains test cases run against the
- Spinner sample application.
- To learn more about the application and how to run it,
- please read the
- <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a> tutorial.
- </dd>
- <dt><a href="TicTacToeLib/index.html">TicTacToeLib</a></dt>
- <dd>
- An example of an Android library project that provides a game-play
- Activity to any dependent application project. For an example of
- how an application can use the code and resources in an Android
- library project, see the <a
- href="{@docRoot}resources/samples/TicTacToeMain/index.html">TicTacToeMain</a>
- sample application.
- </dd>
- <dt><a href="TicTacToeMain/index.html">TicTacToeMain</a></dt>
- <dd>
- An example of an Android application that makes use of code and
- resources provided in an Android library project. Specifically, this
- application uses code and resources provided in the <a
- href="{@docRoot}resources/samples/TicTacToeLib/index.html">TicTacToeLib</a> library project.
- </dd>
- <dt><a href="Wiktionary/index.html">Wiktionary</a></dt>
- <dd>An example of creating interactive widgets for display on the Android
- home screen.</dd>
-
- <dt><a href="WiktionarySimple/index.html">Wiktionary (Simplified)</a></dt>
- <dd>A simple Android home screen widgets example.</dd>
-</dl>
-
-
-<div class="special">
-<p>For more sample applications, check out
-<a href="http://code.google.com/p/apps-for-android/">apps-for-android</a>, a
-collection of open source applications that demonstrate various Android APIs.
-</p>
-</div>
-
+<p><strong>This document has moved. Please go to <a
+href="http://developer.android.com/resources/browser.html?tag=sample">List of Sample
+Apps</a>.</strong></p>
diff --git a/docs/html/sdk/android-2.3.3.jd b/docs/html/sdk/android-2.3.3.jd
index dbc48f4..6d60fcc 100644
--- a/docs/html/sdk/android-2.3.3.jd
+++ b/docs/html/sdk/android-2.3.3.jd
@@ -54,7 +54,7 @@
first.</p>
<p>For a high-level introduction to Android 2.3, see the <a
-href="http://developer.android.com/sdk/android-2.3-highlights.html">Platform Highlights</a>.</p>
+href="{@docRoot}sdk/android-2.3-highlights.html">Platform Highlights</a>.</p>
<h2 id="relnotes">Revisions</h2>
diff --git a/docs/html/sdk/android-2.3.jd b/docs/html/sdk/android-2.3.jd
index 734d97b..e7aa0fa 100644
--- a/docs/html/sdk/android-2.3.jd
+++ b/docs/html/sdk/android-2.3.jd
@@ -51,7 +51,7 @@
first.</p>
<p>For a high-level introduction to Android {@sdkPlatformVersion}, see the <a
-href="http://developer.android.com/sdk/android-{@sdkPlatformVersion}-highlights.html">Platform Highlights</a>.</p>
+href="{@docRoot}sdk/android-{@sdkPlatformVersion}-highlights.html">Platform Highlights</a>.</p>
<h2 id="relnotes">Revisions</h2>
diff --git a/docs/html/sdk/android-3.0.jd b/docs/html/sdk/android-3.0.jd
index 2c8a7f0..136bcd9 100644
--- a/docs/html/sdk/android-3.0.jd
+++ b/docs/html/sdk/android-3.0.jd
@@ -1,4 +1,6 @@
page.title=Android 3.0 Platform Preview
+sdk.platform.version=3.0
+sdk.platform.apiLevel=11
@jd:body
<div id="qv-wrapper">
@@ -6,6 +8,7 @@
<h2>In this document</h2>
<ol>
+ <li><a href="#relnotes">Revisions</a></li>
<li><a href="#api">API Overview</a></li>
<li><a href="#api-level">API Level</a></li>
<li><a href="#apps">Built-in Applications</a></li>
@@ -16,7 +19,7 @@
<h2>Reference</h2>
<ol>
<li><a
-href="{@docRoot}sdk/api_diff/honeycomb/changes.html">API
+href="{@docRoot}sdk/api_diff/11/changes.html">API
Differences Report »</a> </li>
</ol>
@@ -28,18 +31,51 @@
</div>
</div>
-<p><em>API Level:</em> <b>Honeycomb</b></p>
-<p>For developers, the Android 3.0 preview is available as a downloadable component for the
-Android SDK.</p>
+<p><em>API Level:</em> <strong>{@sdkPlatformApiLevel}</strong></p>
-<p class="note"><strong>Note:</strong> Read the <a
-href="{@docRoot}sdk/preview/start.html">Getting Started</a> guide for important information
-about setting up your development environment and limitiations of the Android 3.0 preview.</p>
+<p>For developers, the Android {@sdkPlatformVersion} platform is available as a downloadable
+component for the Android SDK. The downloadable platform includes an Android library and system
+image, as well as a set of emulator skins and more. The downloadable platform includes no external
+libraries.</p>
+
+<p>To get started developing or testing against Android {@sdkPlatformVersion}, use the Android SDK
+Manager to download the platform into your SDK. For more information, see <a
+href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a>. If you are new to Android, <a
+href="{@docRoot}sdk/index.html">download the SDK Starter Package</a> first.</p>
+
+<p>For a high-level introduction to Android {@sdkPlatformVersion}, see the <a
+href="{@docRoot}sdk/android-{@sdkPlatformVersion}-highlights.html">Platform
+Highlights</a>.</p>
+<h2 id="relnotes">Revisions</h2>
+<p>To determine what revision of the Android {@sdkPlatformVersion} platform you have installed,
+refer to the "Installed Packages" listing in the Android SDK and AVD Manager.</p>
+
+
+<div class="toggle-content opened" style="padding-left:1em;">
+
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" alt="" />
+ Android {@sdkPlatformVersion}, Revision 1</a> <em>(February 2011)</em>
+ </a></p>
+
+ <div class="toggle-content-toggleme" style="padding-left:2em;">
+
+<dl>
+
+<dt>Dependencies:</dt>
+<dd>
+<p>Requires <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r10</a> or higher.</p>
+</dd>
+
+</dl>
+
+ </div>
+</div>
@@ -49,6 +85,9 @@
including new features and changes in the framework API since the previous version.</p>
+
+
+
<h3>Fragments</h3>
<p>A fragment is a new framework component that allows you to separate distinct elements of an
@@ -65,9 +104,9 @@
<p>Additionally:</p>
<ul>
- <li>Fragments are self-contained and can be reused in multiple activities</li>
- <li>Fragments can be added, removed, replaced and animated inside the activity</li>
- <li>Fragment can be added to a back stack managed by the activity, preserving the state of
+ <li>Fragments are self-contained and you can reuse them in multiple activities</li>
+ <li>You can add, remove, replace and animate fragments inside the activity</li>
+ <li>You can add fragments to a back stack managed by the activity, preserving the state of
fragments as they are changed and allowing the user to navigate backward through the different
states</li>
<li>By <a
@@ -80,8 +119,8 @@
<p>To manage the fragments in your activity, you must use the {@link
android.app.FragmentManager}, which provides several APIs for interacting with fragments, such
-as finding fragments in the activity and popping fragments off the back stack to restore them
-after they've been removed or hidden.</p>
+as finding fragments in the activity and popping fragments off the back stack to restore their
+previous state.</p>
<p>To perform a transaction, such as add or remove a fragment, you must create a {@link
android.app.FragmentTransaction}. You can then call methods such as {@link
@@ -92,7 +131,10 @@
the activity.</p>
<p>For more information about using fragments, read the <a
-href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> documentation. Several
+samples are also available in the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">
+API Demos</a> application.</p>
@@ -101,49 +143,51 @@
<p>The Action Bar is a replacement for the traditional title bar at the top of the activity window.
It includes the application logo in the left corner and provides a new interface for items in the
-activity's Options Menu. Additionally, the Action Bar allows you to:</p>
+<a href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a>. Additionally, the
+Action Bar allows you to:</p>
<ul>
- <li>Include select menu items directly in the Action Bar—as "action
-items"—for quick access to global user actions.
- <p>In your XML declaration for the menu item, include the attribute, {@code
-android:showAsAction} with a value of {@code "ifRoom"}. When there's enough room in the
-Action Bar, the menu item appears directly in the bar. Otherwise, the item is placed in the
-overflow menu, revealed by the icon on the right side of the Action Bar.</p></li>
+ <li>Add menu items directly in the Action Bar—as "action items."
+ <p>In your XML declaration for the menu item, include the {@code
+android:showAsAction} attribute with a value of {@code "ifRoom"}. When there's enough room, the menu
+item appears directly in the Action Bar. Otherwise, the item is placed in the
+overflow menu, revealed by the menu icon on the right side of the Action Bar.</p></li>
- <li>Add interactive widgets to the Action Bar—as "action views"—such as a search box.
- <p>In the XML for the menu item that should behave as an action view, include the {@code
-android:actionViewLayout} attribute with a layout
-resource for the action view or {@code android:actionViewClass} with the class name of the
-widget. Like action items, an action view appears only when there's room for it in the Action
-Bar. If there's not enough room, it is placed in the overflow menu and behaves like a regular
-menu item (for example, an item can provide a {@link android.widget.SearchView} as an action
-view, but when in the overflow menu, selecting the item activates the search dialog).</p></li>
+ <li>Replace an action item with a widget (such as a search box)—creating an
+"action view."
+ <p>In the XML declaration for the menu item, add the {@code android:actionViewLayout} attribute
+with a layout resource or the {@code android:actionViewClass} attribute with the class name of a
+widget. (You must also declare the {@code android:showAsAction} attribute so that the item appears
+in the Action Bar.) If there's not enough room in the Action Bar and the item appears in the
+overflow menu, it behaves like a regular menu item and does not show the widget.</p></li>
- <li>Add an action to the application logo when tapped and replace it with a custom logo
+ <li>Add an action to the application logo and replace it with a custom logo
<p>The application logo is automatically assigned the {@code android.R.id.home} ID,
-which the system deliveres to your activity's {@link android.app.Activity#onOptionsItemSelected
-onOptionsItemSelected()} callback when tapped. Simply respond to this ID in your callback
+which the system delivers to your activity's {@link android.app.Activity#onOptionsItemSelected
+onOptionsItemSelected()} callback when touched. Simply respond to this ID in your callback
method to perform an action such as go to your application's "home" activity.</p>
- <p>To replace the icon with a logo, </p></li>
+ <p>To replace the icon with a logo, specify your application logo in the manifest file with the
+<a href="{@docRoot}guide/topics/manifest/application-element.html#logo">{@code android:logo}</a>
+attribute, then call {@link android.app.ActionBar#setDisplayUseLogoEnabled
+setDisplayUseLogoEnabled(true)} in your activity.</p></li>
- <li>Add breadcrumbs for navigating backward through fragments</li>
- <li>Add built in tabs and a drop-down list for navigation</li>
- <li>Customize the Action Bar themes and custom backgrounds</li>
+ <li>Add breadcrumbs to navigate backward through the back stack of fragments</li>
+ <li>Add tabs or a drop-down list to navigate through fragments</li>
+ <li>Customize the Action Bar with themes and backgrounds</li>
</ul>
-<p>The Action Bar is standard for all applications that set either the <a
+<p>The Action Bar is standard for all applications that use the new holographic theme, which is
+also standard when you set either the <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
android:minSdkVersion}</a> or <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-android:targetSdkVersion}</a> to {@code "Honeycomb"}. (The "Honeycomb" API Level is provisional
-and effective only while using the preview SDK—you must change it to the official API
-Level when the final SDK becomes available—see <a
-href="{@docRoot}sdk/preview/start.html">Getting Started</a> for more information.)</p>
+android:targetSdkVersion}</a> to {@code "11"}.</p>
<p>For more information about the Action Bar, read the <a
-href="{@docRoot}guide/topics/ui/actionbar.html">Action
-Bar</a> developer guide.</p>
+href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> documentation. Several
+samples are also available in the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#ActionBar">
+API Demos</a> application.</p>
@@ -153,97 +197,123 @@
<p>Applications can now copy and paste data (beyond mere text) to and from the system-wide
clipboard. Clipped data can be plain text, a URI, or an intent.</p>
-<p>By providing the system access to your data in a content provider, the user can copy complex
-content (such as an image or data structure) from your application and paste it into another
-application that supports that type of content.</p>
+<p>By providing the system access to the data you want the user to copy, through a content provider,
+the user can copy complex content (such as an image or data structure) from your application and
+paste it into another application that supports that type of content.</p>
<p>To start using the clipboard, get the global {@link android.content.ClipboardManager} object
by calling {@link android.content.Context#getSystemService getSystemService(CLIPBOARD_SERVICE)}.</p>
-<p>To create an item to attach to the clipboard ("copy"), you need to create a new {@link
+<p>To copy an item to the clipboard, you need to create a new {@link
android.content.ClipData} object, which holds one or more {@link android.content.ClipData.Item}
-objects, each describing a single entity. To create a {@link android.content.ClipData} object with
-just one {@link android.content.ClipData.Item}, you can use one of the helper methods, such as
-{@link android.content.ClipData#newPlainText newPlainText()}, {@link
+objects, each describing a single entity. To create a {@link android.content.ClipData} object
+containing just one {@link android.content.ClipData.Item}, you can use one of the helper methods,
+such as {@link android.content.ClipData#newPlainText newPlainText()}, {@link
android.content.ClipData#newUri newUri()}, and {@link android.content.ClipData#newIntent
newIntent()}, which each return a {@link android.content.ClipData} object pre-loaded with the
-appropriate {@link android.content.ClipData.Item}.</p>
+{@link android.content.ClipData.Item} you provide.</p>
<p>To add the {@link android.content.ClipData} to the clipboard, pass it to {@link
android.content.ClipboardManager#setPrimaryClip setPrimaryClip()} for your instance of {@link
android.content.ClipboardManager}.</p>
-<p>You can then acquire ("paste") a file from the clipboard by calling {@link
+<p>You can then read a file from the clipboard (in order to paste it) by calling {@link
android.content.ClipboardManager#getPrimaryClip()} on the {@link
android.content.ClipboardManager}. Handling the {@link android.content.ClipData} you receive can
-be more complicated and you need to be sure you can actually handle the data type.</p>
+be complicated and you need to be sure you can actually handle the data type in the clipboard
+before attempting to paste it.</p>
-<p>For more information, see the {@link android.content.ClipData} class reference. You can also see
-an example implementation of copy and paste in the <a
-href="{@docRoot}resources/samples/NotePad/index.html">NotePad</a> sample application.</p>
+<p>The clipboard holds only one piece of clipped data (a {@link android.content.ClipData}
+object) at a time, but one {@link android.content.ClipData} can contain multiple {@link
+android.content.ClipData.Item}s.</p>
+
+<p>For more information, read the <a href="{@docRoot}guide/topics/clipboard/copy-paste.html">Copy
+and Paste</a> documentation. You can also see a simple implementation of copy and paste in the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.
+html">API Demos</a> and a more complete implementation in the <a
+href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> application.</p>
<h3>Drag and drop</h3>
-<p>New APIs facilitate the ability for your application to implement drag and drop
-functionality in the UI.</p>
+<p>New APIs simplify drag and drop operations in your application's user interface. A drag
+operation is the transfer of some kind of data—carried in a {@link android.content.ClipData}
+object—from one place to another. The start and end point for the drag operation is a {@link
+android.view.View}, so the APIs that directly handle the drag and drop operations are
+in the {@link android.view.View} class.</p>
+
+<p>A drag and drop operation has a lifecycle that's defined by several drag actions—each
+defined by a {@link android.view.DragEvent} object—such as {@link
+android.view.DragEvent#ACTION_DRAG_STARTED}, {@link android.view.DragEvent#ACTION_DRAG_ENTERED}, and
+{@link android.view.DragEvent#ACTION_DROP}. Each view that wants to participate in a drag
+operation can listen for these actions.</p>
<p>To begin dragging content in your activity, call {@link android.view.View#startDrag startDrag()}
on a {@link android.view.View}, providing a {@link android.content.ClipData} object that represents
-the information to drag, a {@link android.view.View.DragShadowBuilder} to facilitate the "shadow"
-that the user sees while dragging, and an {@link java.lang.Object} that can share information about
-the drag object with views that may receive the object.</p>
+the data to drag, a {@link android.view.View.DragShadowBuilder} to facilitate the "shadow"
+that users see under their fingers while dragging, and an {@link java.lang.Object} that can share
+information about the drag object with views that may receive the object.</p>
-<p>To accept a drag object (receive the "drop") in a
-{@link android.view.View}, register the view with an {@link android.view.View.OnDragListener
-OnDragListener} by
-calling {@link android.view.View#setOnDragListener setOnDragListener()}. When a drag event occurs on
-the view, the system calls {@link android.view.View.OnDragListener#onDrag onDrag()} for the {@link
+<p>To accept a drag object in a {@link android.view.View} (receive the "drop"), register the view
+with an {@link android.view.View.OnDragListener OnDragListener} by calling {@link
+android.view.View#setOnDragListener setOnDragListener()}. When a drag event occurs on the view, the
+system calls {@link android.view.View.OnDragListener#onDrag onDrag()} for the {@link
android.view.View.OnDragListener OnDragListener}, which receives a {@link android.view.DragEvent}
-describing the
-type of event has occurred (such as "drag started", "drag ended", or "drop"). During a drag, the
-system repeatedly calls {@link
-android.view.View.OnDragListener#onDrag onDrag()} for the view underneath the drag, to
-deliver a stream of events. The receiving view can
-inquire the event type delivered to {@link android.view.View#onDragEvent onDragEvent()} by calling
-{@link android.view.DragEvent#getAction getAction()} on the {@link android.view.DragEvent}.</p>
+describing the type of drag action has occurred (such as {@link
+android.view.DragEvent#ACTION_DRAG_STARTED}, {@link android.view.DragEvent#ACTION_DRAG_ENTERED}, and
+{@link android.view.DragEvent#ACTION_DROP}). During a drag, the system repeatedly calls {@link
+android.view.View.OnDragListener#onDrag onDrag()} for the view underneath the drag, to deliver a
+stream of drag events. The receiving view can inquire the event type delivered to {@link
+android.view.View#onDragEvent onDragEvent()} by calling {@link android.view.DragEvent#getAction
+getAction()} on the {@link android.view.DragEvent}.</p>
-<p>Although a drag event may carry a {@link android.content.ClipData} object, this is not related
-to the system clipboard. The data being dragged is passed as a {@link
-android.content.ClipData} object to {@link android.view.View#startDrag startDrag()} and the system
-sends it to the receiving {@link android.view.View} in the {@link android.view.DragEvent} sent to
-{@link android.view.View.OnDragListener#onDrag onDrag()}. A drag and drop operation should never
-put the dragged data in the global system clipboard.</p>
+<p class="note"><strong>Note:</strong> Although a drag event may carry a {@link
+android.content.ClipData} object, this is not related to the system clipboard. A drag and drop
+operation should never put the dragged data in the system clipboard.</p>
+
+<p>For more information, read the <a href="{@docRoot}guide/topics/ui/drag-drop.html">Dragging and
+Dropping</a> documentation. You can also see an implementation of drag and drop in the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">
+API Demos</a> application and the <a
+href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a>
+application.</p>
<h3>App widgets</h3>
-<p>Android 3.0 supports several new widget classes for more interactive app widgets, including:
-{@link
-android.widget.GridView}, {@link android.widget.ListView}, {@link android.widget.StackView}, {@link
-android.widget.ViewFlipper}, and {@link android.widget.AdapterViewFlipper}.</p>
+<p>Android 3.0 supports several new widget classes for more interactive app widgets on the users
+Home screen, including: {@link android.widget.GridView}, {@link android.widget.ListView}, {@link
+android.widget.StackView}, {@link android.widget.ViewFlipper}, and {@link
+android.widget.AdapterViewFlipper}.</p>
-<p>You can also use the new {@link android.widget.RemoteViewsService} to populate
-collection views such as ({@link android.widget.GridView}, {@link android.widget.ListView}, and
-{@link android.widget.StackView}).</p>
+<p>More importantly, you can use the new {@link android.widget.RemoteViewsService} to create app
+widgets with collections, using widgets such as {@link android.widget.GridView}, {@link
+android.widget.ListView}, and {@link android.widget.StackView} that are backed by remote data,
+such as from a content provider.</p>
-<p>{@link android.appwidget.AppWidgetProviderInfo} also supports two new fields: {@link
+<p>The {@link android.appwidget.AppWidgetProviderInfo} class (defined in XML with an {@code
+<appwidget-provider>} element) also supports two new fields: {@link
android.appwidget.AppWidgetProviderInfo#autoAdvanceViewId} and {@link
android.appwidget.AppWidgetProviderInfo#previewImage}. The {@link
android.appwidget.AppWidgetProviderInfo#autoAdvanceViewId} field lets you specify the view ID of the
-app widget subview, which is auto-advanced by the app widget’s host. The
+app widget subview that should be auto-advanced by the app widget’s host. The
{@link android.appwidget.AppWidgetProviderInfo#previewImage} field specifies a preview of what the
app widget looks like and is shown to the user from the widget picker. If this field is not
supplied, the app widget's icon is used for the preview.</p>
-<p>Android also provides a new widget preview tool ({@code WidgetPreview}), located in the SDK
-tools, to take a screenshot of your app widget, which you can use when specifying the {@link
-android.appwidget.AppWidgetProviderInfo#previewImage} field.</p>
+<p>To help create a preview image for your app widget (to specify in the {@link
+android.appwidget.AppWidgetProviderInfo#autoAdvanceViewId} field), the Android emulator includes an
+application called "Widget Preview." To create a preview image, launch this application, select the
+app widget for your application and set it up how you'd like your preview image to appear, then save
+it and place it in your application's drawable resources.</p>
-
+<p>You can see an implementation of the new app widget features in the <a
+href="{@docRoot}resources/samples/StackWidget/index.html">StackView App Widget</a> and <a
+href="{@docRoot}resources/samples/WeatherListWidget/index.html">Weather List Widget</a>
+applications.</p>
@@ -251,7 +321,7 @@
<p>The {@link android.app.Notification} APIs have been extended to support more content-rich status
bar notifications, plus a new {@link android.app.Notification.Builder} class allows you to easily
-control the notification properties.</p>
+create {@link android.app.Notification} objects.</p>
<p>New features include:</p>
<ul>
<li>Support for a large icon in the notification, using {@link
@@ -261,22 +331,32 @@
<li>Support for custom layouts in the status bar ticker, using {@link
android.app.Notification.Builder#setTicker(CharSequence,RemoteViews) setTicker()}.</li>
<li>Support for custom notification layouts to include buttons with {@link
-android.app.PendingIntent}s, for more interactive notification widgets
-(such as to control ongoing music in the background).</li>
+android.app.PendingIntent}s, for more interactive notification widgets. For example, a
+notification can control music playback without starting an activity.</li>
</ul>
-
<h3>Content loaders</h3>
<p>New framework APIs facilitate asynchronous loading of data using the {@link
android.content.Loader} class. You can use it in combination with UI components such as views and
fragments to dynamically load data from worker threads. The {@link
-android.content.CursorLoader} subclass is specially designed to help do so for data queried from
-a {@link android.content.ContentResolver}.</p>
+android.content.CursorLoader} subclass is specially designed to help you do so for data backed by
+a {@link android.content.ContentProvider}.</p>
+<p>All you need to do is implement the {@link android.app.LoaderManager.LoaderCallbacks
+LoaderCallbacks} interface to receive callbacks when a new loader is requested or the data has
+changed, then call {@link android.app.LoaderManager#initLoader initLoader()} to initialize the
+loader for your activity or fragment.</p>
+<p>For more information, read the <a
+href="{@docRoot}guide/topics/providers/loaders.html">Loaders</a> documentation. You can also see
+example code using loaders in the <a
+href="{@docRoot}samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.html">
+FragmentListCursorLoader</a> and <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
+LoaderThrottle</a> samples.</p>
@@ -297,10 +377,10 @@
-<h3>Animation framework</h3>
+<h3 id="animation">Animation framework</h3>
<p>An all new flexible animation framework allows you to animate arbitrary properties of any object
-(View, Drawable, Fragment, Object, or anything else). It allows you to define many aspects of an
+(View, Drawable, Fragment, Object, or anything else). It allows you to define several aspects of an
animation, such as:</p>
<ul>
<li>Duration</li>
@@ -309,13 +389,14 @@
<li>Animator sets to play animations together, sequentially, or after specified delays</li>
<li>Frame refresh delay</li>
</ul>
-
- <p>You can define these animation aspects, and others, for an object's int, float, and hexadecimal
-color values, by default. To animate any other type of value, you tell the system how to calculate
-the values for that given type, by implementing the {@link android.animation.TypeEvaluator}
-interface.</p>
-<p>There are two animators you can use to animate values of a property: {@link
+ <p>You can define these animation aspects, and others, for an object's int, float, and hexadecimal
+color values, by default. That is, when an object has a property field for one of these types, you
+can change its value over time to affect an animation. To animate any other type of value, you tell
+the system how to calculate the values for that given type, by implementing the {@link
+android.animation.TypeEvaluator} interface.</p>
+
+<p>There are two animators you can use to animate the values of a property: {@link
android.animation.ValueAnimator} and {@link android.animation.ObjectAnimator}. The {@link
android.animation.ValueAnimator} computes the animation values, but is not aware of the specific
object or property that is animated as a result. It simply performs the calculations, and you must
@@ -324,7 +405,7 @@
allows you to set the object and property to animate, and it handles all animation work.
That is, you give the {@link android.animation.ObjectAnimator} the object to animate, the
property of the object to change over time, and a set of values to apply to the property over
-time in order to animate it, then start the animation.</p>
+time, then start the animation.</p>
<p>Additionally, the {@link android.animation.LayoutTransition} class enables automatic transition
animations for changes you make to your activity layout. To enable transitions for part of the
@@ -338,7 +419,10 @@
discussed above.</p>
<p>For more information, see the <a
-href="{@docRoot}guide/topics/graphics/animation.html">Animation</a> developer guide.</p>
+href="{@docRoot}guide/topics/graphics/animation.html">Property Animation</a> documentation. You can
+also see several samples using the animation APIs in the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API
+Demos</a> application.</p>
@@ -350,8 +434,11 @@
<li><b>Multiple-choice selection for ListView and GridView</b>
<p>New {@link android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL} mode for {@link
-android.widget.AbsListView#setChoiceMode setChoiceMode()} allows for selecting multiple items
-from a {@link android.widget.ListView} and {@link android.widget.GridView}.</p>
+android.widget.AbsListView#setChoiceMode setChoiceMode()} allows users to select multiple items
+from a {@link android.widget.ListView} or {@link android.widget.GridView}. When used in
+conjunction with the Action Bar, users can select multiple items and then select the action to
+perform from a list of options in the Action Bar (which has transformed into a Multi-choice
+Action Mode).</p>
<p>To enable multiple-choice selection, call {@link
android.widget.AbsListView#setChoiceMode setChoiceMode(CHOICE_MODE_MULTIPLE_MODAL)} and register a
@@ -373,10 +460,11 @@
<li><b>New APIs to transform views</b>
- <p>New APIs allow you to easily apply 2D and 3D transformations to {@link
-android.view.View}s in your activity layout, using a set of object properties that define the view's
+ <p>New APIs allow you to easily apply 2D and 3D transformations to views in your activity
+layout. New transformations are made possible with a set of object properties that define the view's
layout position, orientation, transparency and more.</p>
- <p>New methods to set properties include: {@link android.view.View#setAlpha setAlpha()}, {@link
+ <p>New methods to set the view properties include: {@link android.view.View#setAlpha
+setAlpha()}, {@link
android.view.View#setBottom setBottom()}, {@link android.view.View#setLeft setLeft()}, {@link
android.view.View#setRight setRight()}, {@link android.view.View#setBottom setBottom()}, {@link
android.view.View#setPivotX setPivotX()}, {@link android.view.View#setPivotY setPivotY()}, {@link
@@ -385,14 +473,16 @@
setScaleY()}, {@link android.view.View#setAlpha setAlpha()}, and others.</p>
<p>Some methods also have a corresponding XML attribute that you can specify in your layout
-file. Available attributes include: {@code translationX}, {@code translationY}, {@code rotation},
+file, to apply a default transformation. Available attributes include: {@code translationX}, {@code
+translationY}, {@code rotation},
{@code rotationX}, {@code rotationY}, {@code scaleX}, {@code scaleY}, {@code transformPivotX},
{@code transformPivotY}, and {@code alpha}.</p>
- <p>Using some of these new properties in combination with the new animation framework (discussed
-previously), you can easily create some fancy animations to your views. For example, to rotate a
+ <p>Using some of these new view properties in combination with the new <a
+href="#animation">animation framework</a> (discussed
+above), you can easily apply some fancy animations to your views. For example, to rotate a
view on its y-axis, supply {@link android.animation.ObjectAnimator} with the {@link
-android.view.View}, the "rotationY" property, and the values to use:</p>
+android.view.View}, the "rotationY" property, and the start and end values:</p>
<pre>
ObjectAnimator animator = ObjectAnimator.ofFloat(myView, "rotationY", 0, 360);
animator.setDuration(2000);
@@ -403,16 +493,25 @@
<li><b>New holographic themes</b>
- <p>The standard system widgets and overall look have been redesigned for use on larger screens
-such as tablets and incorporate the new "holographic" UI theme. The system applies these styles
-using the standard <a href="{@docRoot}guide/topics/ui/themes.html">style and theme</a> system.
-Any application that targets the Android 3.0 platform inherits the holographic theme by default.
-However, if your application also applies its own styles, then it will override the holographic
-theme, unless you update your styles to inherit the holographic theme.</p>
+ <p>The standard system widgets and overall look have been redesigned and incorporate a new
+"holographic" user interface theme. The system applies the new theme
+using the standard <a href="{@docRoot}guide/topics/ui/themes.html">style and theme</a> system.</p>
+
+<p>Any application that targets the Android 3.0 platform—by setting either the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
+or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+android:targetSdkVersion}</a> value to {@code "11"}—inherits the holographic theme by default.
+However, if your application also applies its own theme, then your theme will override the
+holographic theme, unless you update your styles to inherit the holographic theme.</p>
<p>To apply the holographic theme to individual activities or to inherit them in your own theme
definitions, use one of several new {@link android.R.style#Theme_Holo Theme.Holo}
-themes.</p>
+themes. If your application is compatible with version of Android lower than 3.0 and applies
+custom themes, then you should <a
+href="{@docRoot}guide/topics/ui/themes.html#SelectATheme">select a theme based on platform
+version</a>.</p>
+
</li>
@@ -430,38 +529,36 @@
each child at a regular interval.</p></li>
<li>{@link android.widget.CalendarView}
- <p>Allows users to select dates from a calendar and you can configure the range of dates
- available. A user can select a date by tapping on it and can scroll and fling
- the calendar to a desired date.</p></li>
+ <p>Allows users to select dates from a calendar by touching the date and can scroll or fling the
+calendar to a desired date. You can configure the range of dates available in the widget.</p></li>
<li>{@link android.widget.ListPopupWindow}
<p>Anchors itself to a host view and displays a list of choices, such as for a list of
suggestions when typing into an {@link android.widget.EditText} view.</p></li>
<li>{@link android.widget.NumberPicker}
- <p>Enables the user to select a number from a predefined range. The widget presents an
- input field and up and down buttons for selecting a number. Touching the input field shows a
- scroll wheel that allows the user to scroll through values or touch again to directly edit the
- current value. It also allows you to map from positions to strings, so that
- the corresponding string is displayed instead of the position index.</p></li>
+ <p>Enables the user to select a number from a predefined range. The widget presents an input
+field and up and down buttons for selecting a number. Touching the input field allows the user to
+scroll through values or touch again to directly edit the current value. It also allows you to map
+positions to strings, so that the corresponding string is displayed instead of the index
+position.</p></li>
<li>{@link android.widget.PopupMenu}
<p>Displays a {@link android.view.Menu} in a modal popup window that's anchored to a view. The
- popup
- appears below the anchor view if there is room, or above it if there is not. If the IME (soft
- keyboard) is visible, the popup does not overlap it until it is touched.</p></li>
+popup appears below the anchor view if there is room, or above it if there is not. If the IME (soft
+keyboard) is visible, the popup does not overlap the IME it until the user touches the
+menu.</p></li>
<li>{@link android.widget.SearchView}
- <p>Provides a search box that works in conjunction with a search provider (in the same manner as
- the traditional <a href="{@docRoot}guide/topics/search/search-dialog.html">search dialog</a>).
-It
- also displays recent query suggestions or custom suggestions as configured by the search
- provider. This widget is particularly useful for offering search in the Action Bar.</p></li>
+ <p>Provides a search box that works in conjunction with the Search Manager (in the same manner
+as the traditional <a href="{@docRoot}guide/topics/search/search-dialog.html">search dialog</a>). It
+can also display recent query suggestions or custom suggestions as configured by the search
+provider. This widget is particularly useful for offering search in the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>.</p></li>
<li>{@link android.widget.StackView}
- <p>A view that displays its children in a 3D stack and allows users to discretely swipe through
- the
- children.</p></li>
+ <p>A view that displays its children in a 3D stack and allows users to swipe through
+ views like a rolodex.</p></li>
</ul>
</li>
@@ -470,13 +567,6 @@
-
-<!--
-<h3>WebKit</h3>
-<h3>JSON (utilities)</h3>
- -->
-
-
<h3>Graphics</h3>
<ul>
@@ -519,7 +609,10 @@
<p>Renderscript is a runtime 3D framework that provides both an API for building 3D scenes as well
as a special, platform-independent shader language for maximum performance. Using Renderscript, you
can accelerate graphics operations and data processing. Renderscript is an ideal way to create
-high-performance 3D effects for applications, wallpapers, carousels, and more.</p></li>
+high-performance 3D effects for applications, wallpapers, carousels, and more.</p>
+<p>For more information, see the <a
+href="{@docRoot}guide/topics/graphics/renderscript.html">3D Rendering and Computation with
+Renderscript</a> documentation.</p></li>
</ul>
@@ -548,7 +641,9 @@
<p>Applications can now pass an M3U playlist URL to the media framework to begin an HTTP Live
streaming session. The media framework supports most of the HTTP Live streaming specification,
-including adaptive bit rate.</p></li>
+including adaptive bit rate. See the <a
+href="{@docRoot}guide/appendix/media-formats.html">Supported Media Formats</a> document for
+more information.</p></li>
<li><b>EXIF data</b>
@@ -599,6 +694,301 @@
+<h3>Keyboard support</h3>
+
+<ul>
+<li>Support for Control, Meta, Caps Lock, Num Lock and Scroll Lock modifiers. For more information,
+see {@link android.view.KeyEvent#META_CTRL_ON} and related fields.</li>
+
+<li>Support for full desktop-style keyboards, including support for keys such as Escape, Home, End,
+Delete and others. You can determine whether key events are coming from a full keyboard by
+querying {@link android.view.KeyCharacterMap#getKeyboardType()} and checking for {@link
+android.view.KeyCharacterMap#FULL KeyCharacterMap.FULL}</li>
+
+<li>{@link android.widget.TextView} now supports keyboard-based cut, copy, paste, and select-all,
+using the key combinations Ctrl+X, Ctrl+C, Ctrl+V, and Ctrl+A. It also supports PageUp/PageDown,
+Home/End, and keyboard-based text selection.</li>
+
+<li>{@link android.view.KeyEvent} adds several new methods to make it easier to check the key
+modifier state correctly and consistently. See {@link android.view.KeyEvent#hasModifiers(int)},
+{@link android.view.KeyEvent#hasNoModifiers()},
+{@link android.view.KeyEvent#metaStateHasModifiers(int,int) metaStateHasModifiers()},
+{@link android.view.KeyEvent#metaStateHasNoModifiers(int) metaStateHasNoModifiers()}.</li>
+
+<li>Applications can implement custom keyboard shortcuts by subclassing {@link
+android.app.Activity}, {@link android.app.Dialog}, or {@link android.view.View} and implementing
+{@link android.app.Activity#onKeyShortcut onKeyShortcut()}. The framework calls this method
+whenever a key is combined with Ctrl key. When creating an <a
+href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a>, you can register keyboard
+shortcuts by setting either the {@code android:alphabeticShortcut} or {@code
+android:numericShortcut} attribute for each <a
+href="{@docRoot}guide/topics/resources/menu-resource.html#item-element">{@code <item>}</a>
+element (or with {@link android.view.MenuItem#setShortcut setShortcut()}).</li>
+
+<li>Android 3.0 includes a new "virtual keyboard" device with the id {@link
+android.view.KeyCharacterMap#VIRTUAL_KEYBOARD KeyCharacterMap.VIRTUAL_KEYBOARD}. The virtual
+keyboard has a desktop-style US key map which is useful for synthesizing key events for testing
+input.</li>
+
+</ul>
+
+
+
+
+<h3>Split touch events</h3>
+
+<p>Previously, only a single view could accept touch events at one time. Android 3.0
+adds support for splitting touch events across views and even windows, so different views can accept
+simultaneous touch events.</p>
+
+<p>Split touch events is enabled by default when an application targets
+Android 3.0. That is, when the application has set either the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
+or <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+android:targetSdkVersion}</a> attribute's value to {@code "11"}.</p>
+
+<p>However, the following properties allow you to disable split touch events across views inside
+specific view groups and across windows.</p>
+
+<ul>
+<li>The {@link android.R.attr#splitMotionEvents android:splitMotionEvents} attribute for view groups
+allows you to disable split touch events that occur between child views in a layout. For example:
+<pre>
+<LinearLayout android:splitMotionEvents="false" ... >
+ ...
+</LinearLayout>
+</pre>
+<p>This way, child views in the linear layout cannot split touch events—only one view can
+receive touch events at a time.</p>
+</li>
+
+<li>The {@link android.R.attr#windowEnableSplitTouch android:windowEnableSplitTouch} style property
+allows you to disable split touch events across windows, by applying it to a theme for the activity
+or entire application. For example:
+<pre>
+<style name="NoSplitMotionEvents" parent="android:Theme.Holo">
+ <item name="android:windowEnableSplitTouch">false</item>
+ ...
+</style>
+</pre>
+<p>When this theme is applied to an <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> or <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>,
+only touch events within the current activity window are accepted. For example, by disabling split
+touch events across windows, the system bar cannot receive touch events at the same time as the
+activity. This does <em>not</em> affect whether views inside the activity can split touch
+events—by default, the activity can still split touch events across views.</p>
+
+<p>For more information about creating a theme, read <a
+href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p>
+</li>
+</ul>
+
+
+
+<h3>WebKit</h3>
+
+<ul>
+ <li>New {@link android.webkit.WebViewFragment} class to create a fragment composed of a
+{@link android.webkit.WebView}.</li>
+ <li>New {@link android.webkit.WebSettings} methods:
+ <ul>
+ <li>{@link
+android.webkit.WebSettings#setDisplayZoomControls setDisplayZoomControls()} allows you to hide
+the on-screen zoom controls while still allowing the user to zoom with finger gestures ({@link
+android.webkit.WebSettings#setBuiltInZoomControls setBuiltInZoomControls()} must be set
+{@code true}).</li>
+ <li>New {@link android.webkit.WebSettings} method, {@link
+android.webkit.WebSettings#setEnableSmoothTransition setEnableSmoothTransition()}, allows you
+to enable smooth transitions when panning and zooming. When enabled, WebView will choose a solution
+to maximize the performance (for example, the WebView's content may not update during the
+transition).</li>
+ </ul>
+ <li>New {@link android.webkit.WebView} methods:
+ <ul>
+ <li>{@link android.webkit.WebView#onPause onPause()} callback, to pause any processing
+associated with the WebView when it becomes hidden. This is useful to reduce unnecessary CPU or
+network traffic when the WebView is not in the foreground.</li>
+ <li>{@link android.webkit.WebView#onResume onResume()} callback, to resume processing
+associated with the WebView, which was paused during {@link android.webkit.WebView#onPause
+onPause()}.</li>
+ <li>{@link android.webkit.WebView#saveWebArchive saveWebArchive()} allows you to save the
+current view as a web archive on the device.</li>
+ <li>{@link android.webkit.WebView#showFindDialog showFindDialog()} initiates a text search in
+the current view.</li>
+ </ul>
+ </li>
+</ul>
+
+
+
+<h3>Browser</h3>
+
+<p>The Browser application adds the following features to support web applications:</p>
+
+<ul>
+ <li><b>Media capture</b>
+ <p>As defined by the <a href="http://dev.w3.org/2009/dap/camera/">HTML Media Capture</a>
+specification, the Browser allows web applications to access audio, image and video capture
+capabilities of the device. For example, the following HTML provides an input for the user to
+capture a photo to upload:</p>
+<pre>
+<input type="file" accept="image/*;capture=camera" />
+</pre>
+<p>Or by excluding the {@code capture=camera} parameter, the user can choose to either capture a
+new image with the camera or select one from the device (such as from the Gallery application).</p>
+ </li>
+
+ <li><b>Device Orientation</b>
+ <p>As defined by the <a
+href="http://dev.w3.org/geo/api/spec-source-orientation.html">Device Orientation Event</a>
+specification, the Browser allows web applications to listen to DOM events that provide information
+about the physical orientation and motion of the device.</p>
+ <p>The device orientation is expressed with the x, y, and z axes, in degrees and motion is
+expressed with acceleration and rotation rate data. A web page can register for orientation
+events by calling {@code window.addEventListener} with event type {@code "deviceorientation"}
+and register for motion events by registering the {@code "devicemotion"} event type.</p>
+ </li>
+
+ <li><b>CSS 3D Transforms</b>
+ <p>As defined by the <a href="http://www.w3.org/TR/css3-3d-transforms/">CSS 3D Transform
+Module</a> specification, the Browser allows elements rendered by CSS to be transformed in three
+dimensions.</p>
+ </li>
+</ul>
+
+
+
+<h3>JSON utilities</h3>
+
+<p>New classes, {@link android.util.JsonReader} and {@link android.util.JsonWriter}, help you
+read and write JSON streams. The new APIs compliment the {@link org.json} classes which manipulate a
+document in memory.</p>
+
+<p>You can create an instance of {@link android.util.JsonReader} by calling
+its constructor method and passing the {@link java.io.InputStreamReader} that feeds the JSON string.
+Then begin reading an object by calling {@link android.util.JsonReader#beginObject()}, read a
+key name with {@link android.util.JsonReader#nextName()}, read the value using methods
+respective to the type, such as {@link android.util.JsonReader#nextString()} and {@link
+android.util.JsonReader#nextInt()}, and continue doing so while {@link
+android.util.JsonReader#hasNext()} is true.</p>
+
+<p>You can create an instance of {@link android.util.JsonWriter} by calling its constructor and
+passing the appropriate {@link java.io.OutputStreamWriter}. Then write the JSON data in a manner
+similar to the reader, using {@link android.util.JsonWriter#name name()} to add a property name
+and an appropriate {@link android.util.JsonWriter#value value()} method to add the respective
+value.</p>
+
+<p>These classes are strict by default. The {@link android.util.JsonReader#setLenient setLenient()}
+method in each class configures them to be more liberal in what they accept. This lenient
+parse mode is also compatible with the {@link org.json}'s default parser.</p>
+
+
+
+
+<h3>New feature constants</h3>
+
+<p>The <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
+manfest element should be used to inform external entities (such as Android Market) of the set of
+hardware and software features on which your application depends. In this release, Android adds the
+following new constants that applications can declare with this element:</p>
+
+<ul>
+ <li>{@link android.content.pm.PackageManager#FEATURE_FAKETOUCH "android.hardware.faketouch"}
+ <p>When declared, this indicates that the application is compatible with a device that offers an
+emulated touchscreen (or better). A device that offers an emulated touchscreen provides a user input
+system that can emulate a subset of touchscreen
+capabilities. An example of such an input system is a mouse or remote control that drives an
+on-screen cursor. Such input systems support basic touch events like click down, click up, and drag.
+However, more complicated input types (such as gestures, flings, etc.) may be more difficult or
+impossible on faketouch devices (and multitouch gestures are definitely not possible).</p>
+ <p>If your application does <em>not</em> require complicated gestures and you do
+<em>not</em> want your application filtered from devices with an emulated touchscreen, you
+should declare {@link
+android.content.pm.PackageManager#FEATURE_FAKETOUCH "android.hardware.faketouch"} with a <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
+element. This way, your application will be available to the greatest number of device types,
+including those that provide only an emulated touchscreen input.</p>
+ <p>All devices that include a touchscreen also support {@link
+android.content.pm.PackageManager#FEATURE_FAKETOUCH "android.hardware.faketouch"}, because
+touchscreen capabilities are a superset of faketouch capabilities. Thus, unless you actually require
+a touchscreen, you should add a <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
+element for faketouch.</p>
+ </li>
+</ul>
+
+
+
+
+<h3>New permissions</h3>
+
+<ul>
+ <li>{@link android.Manifest.permission#BIND_REMOTEVIEWS
+"android.permission.BIND_REMOTEVIEWS"}
+ <p>This must be declared as a required permission in the <a
+href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> manifest
+element for an implementation of {@link android.widget.RemoteViewsService}. For example, when
+creating an App Widget that uses {@link android.widget.RemoteViewsService} to populate a
+collection view, the manifest entry may look like this:</p>
+<pre>
+<service android:name=".widget.WidgetService"
+ android:exported="false"
+ android:permission="android.permission.BIND_REMOTEVIEWS" />
+</pre>
+</ul>
+
+
+
+<h3>New platform technologies</h3>
+
+<ul>
+<li><strong>Storage</strong>
+ <ul>
+ <li>ext4 file system support to enable onboard eMMC storage.</li>
+ <li>FUSE file system to support MTP devices.</li>
+ <li>USB host mode support to support keyboards and USB hubs.</li>
+ <li>Support for MTP/PTP </li>
+ </ul>
+</li>
+
+<li><strong>Linux Kernel</strong>
+ <ul>
+ <li>Upgraded to 2.6.36</li>
+ </ul>
+</li>
+
+<li><strong>Dalvik VM</strong>
+ <ul>
+ <li>New code to support and optimize for SMP</li>
+ <li>Various improvements to the JIT infrastructure</li>
+ <li>Garbage collector improvements:
+ <ul>
+ <li>Tuned for SMP</li>
+ <li>Support for larger heap sizes</li>
+ <li>Unified handling for bitmaps and byte buffers</li>
+ </ul>
+ </li>
+ </ul>
+</li>
+
+<li><strong>Dalvik Core Libraries</strong>
+ <ul>
+ <li>New, much faster implementation of NIO (modern I/O library)</li>
+ <li>Improved exception messages</li>
+ <li>Correctness and performance fixes throughout</li>
+ </ul>
+</li>
+</ul>
+
+
+
+<h3 id="api-diff">API differences report</h3>
+
+<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API Level
+{@sdkPlatformApiLevel}), see the <a
+href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API Differences Report</a>.</p>
@@ -606,21 +996,25 @@
<h2 id="api-level">API Level</h2>
-<p>The Android 3.0 platform delivers an updated version of
-the framework API. Because this is a preview of the Android 3.0 API, it uses a provisional API
-level of "Honeycomb", instead of an integer identifier, which will be provided when the final SDK
-is made available and all APIs are final.</p>
+<p>The Android {@sdkPlatformVersion} platform delivers an updated version of
+the framework API. The Android {@sdkPlatformVersion} API
+is assigned an integer identifier —
+<strong>{@sdkPlatformApiLevel}</strong> — that is
+stored in the system itself. This identifier, called the "API Level", allows the
+system to correctly determine whether an application is compatible with
+the system, prior to installing the application. </p>
-<p>To use APIs introduced in Android 3.0 in your application, you need compile the application
-against the Android library that is provided in the Android 3.0 preview SDK platform and you must
-declare this API Level in your manifest as <code>android:minSdkVersion="Honeycomb"</code>, in the
-<code><uses-sdk></code> element in the application's manifest.</p>
+<p>To use APIs introduced in Android {@sdkPlatformVersion} in your application,
+you need compile the application against the Android library that is provided in
+the Android {@sdkPlatformVersion} SDK platform. Depending on your needs, you might
+also need to add an <code>android:minSdkVersion="{@sdkPlatformApiLevel}"</code>
+attribute to the <code><uses-sdk></code> element in the application's
+manifest. If your application is designed to run only on Android 2.3 and higher,
+declaring the attribute prevents the application from being installed on earlier
+versions of the platform.</p>
-<p>For more information about using this provisional API Level and setting up your environment
-to use the preview SDK, please see the <a href="{@docRoot}sdk/preview/start.html">Getting
-Started</a> document.</p>
-
-
+<p>For more information about how to use API Level, see the <a
+href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document. </p>
<h2 id="apps">Built-in Applications</h2>
@@ -632,6 +1026,7 @@
<tr>
<td style="border:0;padding-bottom:0;margin-bottom:0;">
<ul>
+<li>API Demos</li>
<li>Browser</li>
<li>Calculator</li>
<li>Camera</li>
@@ -646,11 +1041,14 @@
<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
<ul>
<li>Gallery</li>
+<li>Gestures Builder</li>
+<li>Messaging</li>
<li>Music</li>
<li>Search</li>
<li>Settings</li>
-<li>Spare Parts (developer app)</li>
+<li>Spare Parts</li>
<li>Speech Recorder</li>
+<li>Widget Preview</li>
</ul>
</td>
</tr>
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 0bb830c..c283167 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -28,7 +28,7 @@
<p>Android Development Tools (ADT) is a plugin for the Eclipse IDE
that is designed to give you a powerful, integrated environment in which
-to build Android applications. </p>
+to build Android applications.</p>
<p>ADT extends the capabilities of Eclipse to let you quickly set up new Android
projects, create an application UI, add components based on the Android
@@ -95,10 +95,56 @@
</style>
+
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />
+ADT 10.0.0</a> <em>(February 2011)</em>
+ <div class="toggleme">
+
+<dl>
+
+<dt>Dependencies:</dt>
+
+<dd>ADT 10.0.0 is designed for use with SDK Tools r10. If you haven't
+already installed SDK Tools r10 into your SDK, use the Android SDK and AVD Manager to do
+so.</dd>
+
+<dt>General notes:</dt>
+<dd>
+ <ul>
+ <li>The tools now automatically generate Java Programming Language source files (in the <code>gen/</code> directory) and
+ bytecode (in the <code>res/raw/</code> directory) from your <code>.rs</code> files.</li>
+ <li>A Binary XML editor has been added.</li>
+ <li>Traceview is now integrated into the Eclipse UI (<a href="http://tools.android.com/recent/traceviewineclipse">details</a>).</li>
+ <li>The "Go To Declaration" feature for XML and <code>.java</code> files quickly show all the matches in the project
+ and allows you jump to specific items such as string translations or <code>onClick</code> handlers.</li>
+ <li>The Resource Chooser can create items such as dimensions, integers, ids, and booleans.</li>
+ <li>Improvements to the Visual Layout Editor:
+ <ul>
+ <li>A new Palette with categories and rendering previews
+ (<a href="http://tools.android.com/recent/newpalette">details</a>).</li>
+ <li>A Layout action bar.</li>
+ <li>When the Android 3.0 rendering library is selected, layouts render more like they do on devices.
+ This includes rendering of status and title bars to more accurately reflect the actual
+ screen space available to applications.</li>
+ <li>Zoom improvements such as fit to view, persistent scale, and keyboard access.
+ (<a href="http://tools.android.com/recent/zoomimprovements">details</a>).</li>
+ <li>Further improvements to <code><merge></code> layouts, as well as layouts with gesture overlays.</li>
+ <li>Improved rendering error diagnostics.</li>
+ </ul>
+ </li>
+ </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
ADT 9.0.0</a> <em>(January 2011)</em>
<div class="toggleme">
diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd
index 2f53305..10887c6 100644
--- a/docs/html/sdk/ndk/index.jd
+++ b/docs/html/sdk/ndk/index.jd
@@ -59,12 +59,60 @@
}
</style>
-
<div class="toggleable open">
<a href="#"
onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-opened.png"
class="toggle-img"
height="9px"
+ width="9px" /> Android NDK, Revision 6</a> <em>(February 2011)</em>
+
+ <div class="toggleme">
+ <p>This release of the NDK introduces the following header files:</p>
+ <ul>
+ <li><p><code><android/asset_manager.h></code>: Allows access to assets
+ using 64-bit file offsets and sizes. This is useful for very large assets that exceed
+ 2GB, as required by some games. The following APIs are provided:<p>
+ <ul>
+ <li><code>AAsset_getLength64</code></li>
+ <li><code>AAsset_getRemainingLength64</code></li>
+ <li><code>AAsset_openFileDescriptor64</code></li>
+ <li><code>AAsset_seek64</code></li>
+ </ul>
+ </li>
+
+ <li><code><android/input.h></code>: Provides the following AMETA_XXX constants
+ that are related to the new input framework in Honeycomb:
+<pre>
+AMETA_FUNCTION_ON = 0x08,
+AMETA_CTRL_ON = 0x1000,
+AMETA_CTRL_LEFT_ON = 0x2000,
+AMETA_CTRL_RIGHT_ON = 0x4000,
+AMETA_META_ON = 0x10000,
+AMETA_META_LEFT_ON = 0x20000,
+AMETA_META_RIGHT_ON = 0x40000,
+AMETA_CAPS_LOCK_ON = 0x100000,
+AMETA_NUM_LOCK_ON = 0x200000,
+AMETA_SCROLL_LOCK_ON = 0x400000,
+</pre>
+ </li>
+
+ <li><code><android/keycodes></code>: Provides <code>AKEYCODE_XXX</code>
+ constants that are related to the new input framework in Honeycomb.
+ </li>
+
+ <li><code><android/native_activity.h></code>: Adds a new field to the
+ system-allocated <code>ANativeActivity</code> structure named <code>obbPath</code> that
+ contains the path of your application's OBB files, if any.
+ </li>
+ </ul>
+ </div>
+ </div>
+
+<div class="toggleable closed">
+ <a href="#"
+ onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-closed.png"
+ class="toggle-img"
+ height="9px"
width="9px" /> Android NDK, Revision 5b</a> <em>(January 2011)</em>
<div class="toggleme">
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 2ba8076..1b94b2c 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -40,25 +40,15 @@
if:sdk.preview ?>
<li><h2>Android 3.0 Preview SDK</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/preview/start.html">Getting Started</a> <span class="new">new!</span></li>
- <li class="toggle-list">
- <div><a href="<?cs var:toroot ?>sdk/android-3.0.html">
- <span class="en">Android 3.0 Platform</span></a> <span class="new">new!</span></div>
- <ul>
- <li><a href="<?cs var:toroot ?>sdk/api_diff/honeycomb/changes.html">API Differences Report
-»</a></li>
- </ul>
- </li>
+ <li><a href="<?cs var:toroot ?>sdk/preview/start.html">Getting Started</a> <span
+class="new">new!</span></li>
</ul>
</li><?cs
/if ?>
<?cs
if:sdk.preview ?>
- <li><h2>Android 3.0 Preview</h2>
+ <li><h2>Android x.x Preview</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/android-3.0-highlights.html">Platform Highlights</a> <span
-class="new">new!</span></li>
- <li><a href="<?cs var:toroot ?>sdk/preview/index.html">SDK</a> <span class="new">new!</span></li>
</ul>
</li><?cs
/if ?>
@@ -87,18 +77,19 @@
</ul>
<ul>
<li class="toggle-list">
- <div><a href="<?cs var:toroot ?>sdk/android-2.3.3.html">
- <span class="en">Android 2.3.3 Platform</span></a> <span class="new">new!</span></div>
+ <div><a href="<?cs var:toroot ?>sdk/android-3.0.html">
+ <span class="en">Android 3.0 Platform</span></a> <span class="new">new!</span></div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/api_diff/10/changes.html">API Differences Report »</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/android-3.0-highlights.html">Platform Highlights</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/api_diff/11/changes.html">API Differences Report »</a></li>
</ul>
</li>
<li class="toggle-list">
- <div><a href="<?cs var:toroot ?>sdk/android-2.3.html">
- <span class="en">Android 2.3 Platform</span></a></div>
+ <div><a href="<?cs var:toroot ?>sdk/android-2.3.3.html">
+ <span class="en">Android 2.3.3 Platform</span></a> <span class="new">new!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>sdk/android-2.3-highlights.html">Platform Highlights</a></li>
- <li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report »</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/api_diff/10/changes.html">API Differences Report »</a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a></li>
@@ -108,6 +99,13 @@
<li class="toggle-list">
<div><a href="#" onclick="toggle(this.parentNode.parentNode,true); return false;">Older Platforms</a></div>
<ul>
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>sdk/android-2.3.html">
+ <span class="en">Android 2.3 Platform</span></a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report »</a></li>
+ </ul>
+ </li>
<li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-2.0.html">Android 2.0 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.1.html">Android 1.1 Platform</a></li>
@@ -115,7 +113,7 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r9</a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r10</a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
</ul>
</li>
@@ -131,7 +129,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 9.0.0
+ <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 10.0.0
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
<span style="display:none" class="fr"></span>
@@ -153,7 +151,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r5b</a>
+ <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r6</a>
<span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/ndk/overview.html">What is the NDK?</a></li>
</ul>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 97ca8ab0..28d8bdd 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -65,6 +65,34 @@
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+SDK Tools, Revision 10</a> <em>(February 2011)</em>
+ <div class="toggleme">
+ <dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>If you are developing in Eclipse with ADT, note that the SDK Tools r10 is
+designed for use with ADT 10.0.0 and later. After installing SDK Tools r10, we
+highly recommend updating your ADT Plugin to 10.0.0.</p>
+
+<p>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
+Ant</a> 1.8 or later.</p>
+
+<dt>General notes:</dt>
+<dd>
+ <ul>
+ <li>The tools now automatically generate Java Programming Language source files (in the <code>gen</code> directory) and
+ bytecode (in the <code>res/raw</code> directory) from your native <code>.rs</code> files</li>
+ </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
SDK Tools, Revision 9</a> <em>(January 2011)</em>
<div class="toggleme">
<dl>
diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rs b/libs/rs/java/Balls/src/com/android/balls/balls.rs
index fed9963..7dc7660 100644
--- a/libs/rs/java/Balls/src/com/android/balls/balls.rs
+++ b/libs/rs/java/Balls/src/com/android/balls/balls.rs
@@ -52,7 +52,7 @@
int root() {
rsgClearColor(0.f, 0.f, 0.f, 1.f);
- BallControl_t bc = {0};
+ BallControl_t bc;
Ball_t *bout;
if (frame & 1) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index 15c4f44..734f5ad 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -294,7 +294,8 @@
return null;
}
- String value = mResourceData[index].getValue();
+ ResourceValue resValue = mResourceData[index];
+ String value = resValue.getValue();
if (value == null) {
return null;
@@ -308,11 +309,13 @@
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(new FileReader(f));
- ColorStateList colorStateList = ColorStateList.createFromXml(
- mContext.getResources(),
- // FIXME: we need to know if this resource is platform or not
- new BridgeXmlBlockParser(parser, mContext, false));
- return colorStateList;
+ BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+ parser, mContext, resValue.isFramework());
+ try {
+ return ColorStateList.createFromXml(mContext.getResources(), blockParser);
+ } finally {
+ blockParser.ensurePopped();
+ }
} catch (XmlPullParserException e) {
Bridge.getLog().error(LayoutLog.TAG_BROKEN,
"Failed to configure parser for " + value, e, null /*data*/);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
index 38800da..2f54ae6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
@@ -45,6 +45,8 @@
private boolean mStarted = false;
private int mEventType = START_DOCUMENT;
+ private boolean mPopped = true; // default to true in case it's not pushed.
+
/**
* Builds a {@link BridgeXmlBlockParser}.
* @param parser The XmlPullParser to get the content from.
@@ -59,6 +61,7 @@
if (mContext != null) {
mContext.pushParser(this);
+ mPopped = false;
}
}
@@ -82,6 +85,13 @@
return null;
}
+ public void ensurePopped() {
+ if (mContext != null && mPopped == false) {
+ mContext.popParser();
+ mPopped = true;
+ }
+ }
+
// ------- XmlResourceParser implementation
public void setFeature(String name, boolean state)
@@ -249,9 +259,9 @@
}
int ev = mParser.next();
- if (ev == END_TAG && mParser.getDepth() == 1 && mContext != null) {
+ if (ev == END_TAG && mParser.getDepth() == 1) {
// done with parser remove it from the context stack.
- mContext.popParser();
+ ensurePopped();
}
mEventType = ev;
return ev;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 771d89a..0c4b0d3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -76,9 +76,13 @@
"UTF8");
BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
- parser, (BridgeContext) context, false);
+ parser, (BridgeContext) context, false /*platformFile*/);
- inflater.inflate(bridgeParser, this, true);
+ try {
+ inflater.inflate(bridgeParser, this, true);
+ } finally {
+ bridgeParser.ensurePopped();
+ }
}
private InputStream getIcon(String iconName, Density[] densityInOut, String[] pathOut,
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 136b205..fedd789f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -182,8 +182,8 @@
context.setBridgeInflater(mInflater);
mInflater.setFactory2(context);
- mBlockParser = new BridgeXmlBlockParser(params.getLayoutDescription(),
- context, false /* platformResourceFlag */);
+ mBlockParser = new BridgeXmlBlockParser(
+ params.getLayoutDescription(), context, false /* platformResourceFlag */);
return SUCCESS.createResult();
}
@@ -562,13 +562,14 @@
BridgeContext context = getContext();
// create a block parser for the XML
- BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(childXml, context,
- false /* platformResourceFlag */);
+ BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+ childXml, context, false /* platformResourceFlag */);
// inflate the child without adding it to the root since we want to control where it'll
// get added. We do pass the parentView however to ensure that the layoutParams will
// be created correctly.
final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);
+ blockParser.ensurePopped();
invalidateRenderingSize();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index 19392a7..69f46e6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -126,8 +126,13 @@
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(new FileReader(f));
- return ColorStateList.createFromXml(context.getResources(),
- new BridgeXmlBlockParser(parser, context, resValue.isFramework()));
+ BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+ parser, context, resValue.isFramework());
+ try {
+ return ColorStateList.createFromXml(context.getResources(), blockParser);
+ } finally {
+ blockParser.ensurePopped();
+ }
} catch (XmlPullParserException e) {
Bridge.getLog().error(LayoutLog.TAG_BROKEN,
"Failed to configure parser for " + value, e, null /*data*/);
@@ -164,8 +169,6 @@
* @param context the current context
*/
public static Drawable getDrawable(ResourceValue value, BridgeContext context) {
- Drawable d = null;
-
String stringValue = value.getValue();
if (RenderResources.REFERENCE_NULL.equals(stringValue)) {
return null;
@@ -205,9 +208,13 @@
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(new FileReader(f));
- d = Drawable.createFromXml(context.getResources(),
- new BridgeXmlBlockParser(parser, context, value.isFramework()));
- return d;
+ BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+ parser, context, value.isFramework());
+ try {
+ return Drawable.createFromXml(context.getResources(), blockParser);
+ } finally {
+ blockParser.ensurePopped();
+ }
} catch (Exception e) {
// this is an error and not warning since the file existence is checked before
// attempting to parse it.