diff options
Diffstat (limited to 'docs/html/guide/topics')
20 files changed, 1899 insertions, 890 deletions
diff --git a/docs/html/guide/topics/fundamentals.jd b/docs/html/guide/topics/fundamentals.jd index 7118ceb..3e1501c 100644 --- a/docs/html/guide/topics/fundamentals.jd +++ b/docs/html/guide/topics/fundamentals.jd @@ -17,6 +17,7 @@ page.title=Application Fundamentals <li><a href="#appcomp">Application Components</a> <ol> <li><a href="#actcomp">Activating components: intents</a></li> + <li><a href="#endcomp">Shutting down components</a></li> <li><a href="#manfile">The manifest file</a></li> <li><a href="#ifilters">Intent filters</a></li> </ol></li> @@ -27,8 +28,14 @@ page.title=Application Fundamentals <li><a href="#clearstack">Clearing the stack</a></li> <li><a href="#starttask">Starting tasks</a></li> </ol></li> -<li><a href="#procthread">Processes and Threads</a></li> -<li><a href="#lcycles">Lifecycles</a> +<li><a href="#procthread">Processes and Threads</a> + <ol> + <li><a href="#procs">Processes</a></li> + <li><a href="#threads">Threads</a></li> + <li><a href="#rpc">Remote procedure calls</a></li> + <li><a href="#tsafe">Thread-safe methods</a></li> + </ol></li> +<li><a href="#lcycles">Component Lifecycles</a> <ol> <li><a href="#actlife">Activity lifecycle</a></li> <li><a href="#servlife">Service lifecycle</a></li> @@ -40,13 +47,14 @@ page.title=Application Fundamentals <p> Android applications are written in the Java programming language. -The compiled Java code — along with data and -resource files required by the application and a manifest describing the -application — is bundled by the aapt tool into an <i>Android package</i>, -an archive file marked by an {@code .apk} suffix. This file is the vehicle -for distributing the application and installing it on mobile devices; it's -the file users download to their devices. All the code in a single -{@code .apk} file is considered to be one <i>application</i>. +The compiled Java code — along with any data and resource +files required by the application — is bundled by the +<a href="{@docRoot}guide/developing/tools/aapt.html"><code>aapt</code> +tool</a> into an <i>Android package</i>, an archive file +marked by an {@code .apk} suffix. This file is the vehicle +for distributing the application and installing it on mobile devices; +it's the file users download to their devices. All the code in a +single {@code .apk} file is considered to be one <i>application</i>. </p> <p> @@ -76,7 +84,7 @@ in the same Linux process, sharing the same VM. </p> -<h2><a name="appcomp"></a>Application Components</h2> +<h2 id="appcomp">Application Components</h2> <p> A central feature of Android is that one application can make use of elements @@ -125,24 +133,31 @@ current activity start the next one. Each activity is given a default window to draw in. Typically, the window fills the screen, but it might be smaller than the screen and float on top of other windows. An activity can also make use of additional windows — -for example, a window that presents users with vital information when they -select a particular item on-screen, or a pop-up dialog that calls for a user -response in the midst of the activity. +for example, a pop-up dialog that calls for a user response in the midst of +the activity, or a window that presents users with vital information when they +select a particular item on-screen. </p> <p> The visual content of the window is provided by a hierarchy of views — objects derived from the base {@link android.view.View} class. Each view -draws in a particular rectangular space within the window and responds to user -actions directed at that space. Android has a number of ready-made views that -you can use — including buttons, text fields, scroll bars, menu items, -check boxes, and more. A view hierarchy is placed within the activity's -window by the <code>{@link android.app.Activity#setContentView -Activity.setContentView()}</code> method. The <i>content view</i> -is the View object at the root of the hierarchy. -(See <a href="{@docRoot}guide/topics/views/index.html">Views and Layout</a> -for more information on views and the heirarchy.) -</p></dd> +controls a particular rectangular space within the window. Parent views +contain and organize the layout of their children. Leaf views (those at the +bottom of the hierarchy) draw in the rectangles they control and respond to +user actions directed at that space. Thus, views are where the activity's +interaction with the user takes place. For example, a view might display +a small image and initiate an action when the user taps that image. Android +has a number of ready-made views that you can use — including buttons, +text fields, scroll bars, menu items, check boxes, and more. +</p> + +<p> +A view hierarchy is placed within an activity's window by the +<code>{@link android.app.Activity#setContentView Activity.setContentView()}</code> +method. The <i>content view</i> is the View object at the root of the hierarchy. +(See the separate <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> +document for more information on views and the hierarchy.) +</p> <p><dt><b>Services</b></dt> <dd>A <i>service</i> doesn't have a visual user interface, but rather runs in @@ -152,13 +167,13 @@ data over the network or calculate something and provide the result to activitie that need it. Each service extends the {@link android.app.Service} base class. <p> -A good example is a media player playing songs from a play list. The player +A prime example is a media player playing songs from a play list. The player application would probably have one or more activities that allow the user to choose songs and start playing them. However, the music playback itself would not be handled by an activity because users will expect the music to keep playing even after they leave the player and begin something different. To keep the music going, the media player activity could start a service to run -in the background. The system will then keep the music playback service running +in the background. The system would then keep the music playback service running even after the activity that started it leaves the screen. </p> @@ -180,8 +195,10 @@ user interface, they often spawn another thread for time-consuming tasks <dd>A <i>broadcast receiver</i> is a component that does nothing but receive and react to broadcast announcements. Many broadcasts originate in system code — for example, announcements that the timezone has changed, -that the battery is low, that the keyboard has been exposed, or that the user -changed a language preference. +that the battery is low, that a picture has been taken, or that the user +changed a language preference. Applications can also initiate broadcasts +— for example, to let other applications know that some data has been +downloaded to the device and is available for them to use. <p> An application can have any number of broadcast receivers to respond to any @@ -227,19 +244,19 @@ is available, creating the instance if necessary. </p> -<h3><a name="actcomp"></a>Activating components: intents</h3> +<h3 id="actcomp">Activating components: intents</h3> <p> Content providers are activated when they're targeted by a request from a ContentResolver. The other three components — activities, services, and broadcast receivers — are activated by asynchronous messages called <i>intents</i>. An intent is an {@link android.content.Intent} -object that holds the content of the message. Among other things, it names -the action an activity or service is being requested to take and specifies -the URI of the data to act on. For broadcast receivers, it names the -action being announced. For example, it might convey a request for +object that holds the content of the message. For activities and services, +it names the action being requested and specifies the URI of the data to +act on, among other things. For example, it might convey a request for an activity to present an image to the user or let the user edit some -text. Or it might announce to interested broadcast receivers that the +text. For broadcast receivers, the Intent object names the action being +announced. For example, it might announce to interested parties that the camera button has been pressed. </p> @@ -281,13 +298,19 @@ onStart()}</code> method and passes it the Intent object.</p> Similarly, an intent can be passed to <code>{@link android.content.Context#bindService Context.bindService()}</code> to establish an ongoing connection between the calling component and a -target service. It initiates the service if it's not already running. -The service receives the Intent object in +target service. The service receives the Intent object in an <code>{@link android.app.Service#onBind onBind()}</code> call. -For example, an activity might establish a connection with the music -playback service mentioned earlier so that it could provide the user -with an interface for controlling the playback. The activity would -call {@code bindService()} to set up that connection. +(If the service is not already running, {@code bindService()} can +optionally start it.) For example, an activity might establish a connection +with the music playback service mentioned earlier so that it can provide +the user with the means (a user interface) for controlling the playback. +The activity would call {@code bindService()} to set up that connection, +and then call methods defined by the service to affect the playback. +</p> + +<p> +A later section, <a href="#rpc">Remote procedure calls</a>, has more details +about binding to a service. </p> </li> @@ -304,12 +327,49 @@ android.content.BroadcastReceiver#onReceive onReceive()}</code> methods.</p></li </ul> <p> -For more on intent messages, see the separate article, <a -href="{@docRoot}guide/topics/intents/intents-filters.html">Intents +For more on intent messages, see the separate article, +<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>. +</p> -<h3><a name="manfile"></a>The manifest file</h3> +<h3 id="endcomp">Shutting down components</h3> + +<p> +A content provider is active only while it's responding to a request from +a ContentResolver. And a broadcast receiver is active only while it's +responding to a broadcast message. So there's no need to explicitly shut +down these components. +</p> + +<p> +Activities, on the other hand, provide the user interface. They're +in a long-running conversation with the user and may remain active, +even when idle, as long as the conversation continues. Similarly, services +may also remain running for a long time. So Android has methods to shut +down activities and services in an orderly way: +</p> + +<ul> +<li>An activity can be shut down by calling its +<code>{@link android.app.Activity#finish finish()}</code> method. One activity can +shut down another activity (one it started with {@code startActivityForResult()}) by +calling <code>{@link android.app.Activity#finishActivity finishActivity()}</code>.</li> + +<li>A service can be stopped by calling its +<code>{@link android.app.Service#stopSelf stopSelf()}</code> method, or by calling +<code>{@link android.content.Context#stopService Context.stopService()}</code>.</li> +</ul> + +<p> +Components might also be shut down by the system when they are no longer being +used or when Android must reclaim memory for more active components. A later +section, <a href="#lcycles">Component Lifecycles</a>, discusses this +possibility and its ramifications in more detail. +</p> + + +<h3 id="manfile">The manifest file</h3> <p> Before Android can start an application component, it must learn that @@ -344,8 +404,9 @@ components. For example, an activity might be declared as follows: </manifest></pre> <p> -The {@code name} attribute of the {@code <activity>} element -names the {@link android.app.Activity} subclass that implements the +The {@code name} attribute of the +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +element names the {@link android.app.Activity} subclass that implements the activity. The {@code icon} and {@code label} attributes point to resource files containing an icon and label that can be displayed to users to represent the activity. @@ -353,24 +414,28 @@ to users to represent the activity. <p> The other components are declared in a similar way — -{@code <service>} elements for services, {@code <receiver>} -elements for broadcast receivers, and {@code <provider>} elements -for content providers. Activities, services, and content providers that -are not declared in the manifest are not visible to the system and are -consequently never run. Broadcast receivers can be declared in the -manifest, or they can be created dynamically in code (as -{@link android.content.BroadcastReceiver} objects) -and registered with the system by calling <code>{@link -android.content.Context#registerReceiver Context.registerReceiver()}</code>. +<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code> +elements for services, +<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code> +elements for broadcast receivers, and +<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code> +elements for content providers. Activities, services, and content providers +that are not declared in the manifest are not visible to the system and are +consequently never run. However, broadcast receivers can either be +declared in the manifest, or they can be created dynamically in code +(as {@link android.content.BroadcastReceiver} objects) +and registered with the system by calling +<code>{@link android.content.Context#registerReceiver Context.registerReceiver()}</code>. </p> <p> For more on how to structure a manifest file for your application, see -<a href="{@docRoot}guide/topics/manifest/manifest.html">The Manifest File</a>. +<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The +AndroidManifest.xml File</a>. </p> -<h3><a name="ifilters"></a>Intent filters</h3> +<h3 id="ifilters">Intent filters</h3> <p> An Intent object can explicitly name a target component. If it does, @@ -442,7 +507,7 @@ and Intent Filters</a>. </p> -<h2><a name="acttask"></a>Activities and Tasks</h2> +<h2 id="acttask">Activities and Tasks</h2> <p> As noted earlier, one activity can start another, including one defined @@ -467,14 +532,14 @@ the one that is the focus for user actions. When one activity starts another, the new activity is pushed on the stack; it becomes the running activity. The previous activity remains in the stack. When the user presses the BACK key, the current activity is popped from the stack, and the previous one resumes as -the running activity. Activities in the stack are never rearranged, only -pushed and popped. +the running activity. </p> <p> The stack contains objects, so if a task has more than one instance of the same Activity subclass open — multiple map viewers, for example — the -stack has a separate entry for each instance. +stack has a separate entry for each instance. Activities in the stack are never +rearranged, only pushed and popped. </p> <p> @@ -505,7 +570,8 @@ The behavior just described is the default behavior for activities and tasks. But there are ways to modify almost all aspects of it. The association of activities with tasks, and the behavior of an activity within a task, is controlled by the interaction between flags set in the Intent object that -started the activity and attributes set in the activity's {@code <activity>} +started the activity and attributes set in the activity's +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> element in the manifest. Both requester and respondent have a say in what happens. </p> @@ -529,19 +595,19 @@ The principal {@code <activity>} attributes are: <p> The following sections describe what some of these flags and attributes do, -and how they interact. +how they interact, and what considerations should govern their use. </p> -<h3><a name="afftask"></a>Affinities and new tasks</h3> +<h3 id="afftask">Affinities and new tasks</h3> <p> By default, all the activities in an application have an <i>affinity</i> for each other — that is, there's a preference for them all to belong to the same task. However, an individual affinity can be set for each activity -with the {@code taskAffinity} attribute. Activities defined in different -applications can share an affinity, or activities defined in the same -application can be assigned different affinities. +with the {@code taskAffinity} attribute of the {@code <activity>} element. +Activities defined in different applications can share an affinity, or activities +defined in the same application can be assigned different affinities. The affinity comes into play in two circumstances: When the Intent object that launches an activity contains the {@code FLAG_ACTIVITY_NEW_TASK} flag, and when an activity has its {@code allowTaskReparenting} attribute set @@ -550,26 +616,28 @@ to "{@code true}". <dl> <dt>The <code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code> flag</dt> -<dd>As mentioned earlier, a new activity is, by default, launched into +<dd>As described earlier, a new activity is, by default, launched into the task of the activity that called {@code startActivity()}. It's pushed onto the same stack as the caller. However, if the Intent object passed to {@code startActivity()} contains the {@code FLAG_ACTIVITY_NEW_TASK} flag, the system looks for a different task to house the new activity. Often, as the name of the flag implies, it's a new task. However, it -doesn't have to be. If there's an existing task with the same affinity -as the new activity, the activity is launched into that task. If not, -it begins a new task.</dd> - -<dt>The {@code allowTaskReparenting} attribute</dt> -<dd>If an activity has its {@code allowTaskReparenting} attribute is -set to "{@code true}", it can move from the task it starts in to the task +doesn't have to be. If there's already an existing task with the same +affinity as the new activity, the activity is launched into that task. If +not, it begins a new task.</dd> + +<dt>The <code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">allowTaskReparenting</a></code> +attribute</dt> +<dd>If an activity has its {@code allowTaskReparenting} attribute set +to "{@code true}", it can move from the task it starts in to the task it has an affinity for when that task comes to the fore. For example, suppose that an activity that reports weather conditions in selected cities is defined as part of a travel application. It has the same affinity as other activities in the same application (the default affinity) and it allows reparenting. One of your activities starts the weather reporter, so it initially belongs to the same task as -your activity. However, when the travel application, next comes forward, +your activity. However, when the travel application next comes forward, the weather reporter will be reassigned to and displayed with that task.</dd> </dl> @@ -580,65 +648,116 @@ affinities to the activities associated with each of them. </p> -<h3><a name="lmodes"></a>Launch modes</h3> +<h3 id="lmodes">Launch modes</h3> <p> There are four different launch modes that can be assigned to an {@code -<activity>} element's {@code launchMode} attribute: +<activity>} element's +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code> +attribute: </p> -<p style="margin-left: 2em">"{@code standard}" (the default value) +<p style="margin-left: 2em">"{@code standard}" (the default mode) <br>"{@code singleTop}" <br>"{@code singleTask}" <br>"{@code singleInstance}"</p> <p> -The launch mode determines three things: +The modes differ from each other on these four points: </p> <ul> -<li>Whether the activity can belong to a task that includes other -activities. The answer is yes for all the modes except -"{@code singleInstance}". A "{@code singleInstance}" activity is always -the only activity in its task. If it tries to launch another activity, -that activity is assigned to a different task — as if {@code -FLAG_ACTIVITY_NEW_TASK} was in the intent.</li> - -<li><p>Whether the activity always begins a task. For "{@code singleTask}" -and "{@code singleInstance}" the answer is yes. They mark activities that -can only be the root activities of a task; they define a task. In contrast, -"{@code standard}" and "{@code singleTop}" activities can belong to any task. + +<li><b>Which task will hold the activity that responds to the intent</b>. +For the "{@code standard}" and "{@code singleTop}" modes, it's the task that +originated the intent (and called +<code>{@link android.content.Context#startActivity startActivity()}</code>) +— unless the Intent object contains the +<code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code> flag. +In that case, a different task is chosen as described in the previous +section, <a href="#afftask">Affinities and new tasks</a>. + +<p> +In contrast, the "{@code singleTask}" and "{@code singleInstance}" modes mark +activities that are always at the root of a task. They define a task; they're +never launched into another task. +</p> + +<li><p><b>Whether there can be multiple instances of the activity</b>. +A "{@code standard}" or "{@code singleTop}" activity can be instantiated +many times. They can belong to multiple tasks, and a given task can have +multiple instances of the same activity. +</p> + +<p> +In contrast, "{@code singleTask}" and "{@code singleInstance}" activities +are limited to just one instance. Since these activities are at the root +of a task, this limitation means that there is never more than a single +instance of the task on the device at one time. +</p> + +<li><p><b>Whether the instance can have other activities in its task</b>. +A "{@code singleInstance}" activity stands alone as the only activity in its +task. If it starts another activity, that activity will be launched into a +different task regardless of its launch mode — as if {@code +FLAG_ACTIVITY_NEW_TASK} was in the intent. In all other respects, the +"{@code singleInstance}" mode is identical to "{@code singleTask}".</p> + +<p> +The other three modes permit multiple activities to belong to the task. +A "{@code singleTask}" activity will always be the root activity of the task, +but it can start other activities that will be assigned to its +task. Instances of "{@code standard}" and "{@code singleTop}" +activities can appear anywhere in a stack. </p></li> -<li><p>Whether an existing instance of the activity can handle new -intents. The answer is yes for all the modes except "{@code standard}". -Existing "{@code singleTask}" and "{@code singleInstance}" activities -handle all new intents that come their way; a new instance is never -created. In the case of "{@code singleTask}", all other activities in -the task are popped from the stack, so that the root "{@code singleTask}" -activity is at the top and in position to respond to the intent. +<li><b>Whether a new instance of the class will be launched +to handle a new intent</b>. For the default "{@code standard}" mode, a +new instance is created to respond to every new intent. Each instance +handles just one intent. For the "{@code singleTop}" mode, an existing +instance of the class is re-used to handle a new intent if it resides +at the top of the activity stack of the target task. If it does not +reside at the top, it is not re-used. Instead, a new instance +is created for the new intent and pushed on the stack. + +<p> +For example, suppose a task's activity stack consists of root activity A with +activities B, C, and D on top in that order, so the stack is A-B-C-D. An intent +arrives for an activity of type D. If D has the default "{@code standard}" launch +mode, a new instance of the class is launched and the stack becomes A-B-C-D-D. +However, if D's launch mode is "{@code singleTop}", the existing instance is +expected to handle the new intent (since it's at the top of the stack) and the +stack remains A-B-C-D. </p> <p> -If a "{@code singleTop}" activity is at the -top of its stack, that object is expected to handle any new intents. -However, if it's farther down the stack, a new instance is created for -the intent and pushed on the stack. +If, on the other hand, the arriving intent is for an activity of type B, a new +instance of B would be launched no matter whether B's mode is "{@code standard}" +or "{@code singleTop}" (since B is not at the top of the stack), so the resulting +stack would be A-B-C-D-B. </p> <p> -In contrast, a new instance of a "{@code standard}" activity is always -created for each new intent. +As noted above, there's never more than one instance of a "{@code singleTask}" +or "{@code singleInstance}" activity, so that instance is expected to handle +all new intents. A "{@code singleInstance}" activity is always at the top of +the stack (since it is the only activity in the task), so it is always in +position to handle the intent. However, a "{@code singleTask}" activity may +or may not have other activities above it in the stack. If it does, it is not +in position to handle the intent, and the intent is dropped. (Even though the +intent is dropped, its arrival would have caused the task to come to the +foreground, where it would remain.) </p> </li> + </ul> <p> When an existing activity is asked to handle a new intent, the Intent -object is passed to the activity in an <code>{@link android.app.Activity#onNewIntent -onNewIntent()}</code> call. (The intent object that originally started the -activity can be retrieved by calling -<code>{@link android.app.Activity#getIntent getIntent()}</code>.) +object is passed to the activity in an +<code>{@link android.app.Activity#onNewIntent onNewIntent()}</code> call. +(The intent object that originally started the activity can be retrieved by +calling <code>{@link android.app.Activity#getIntent getIntent()}</code>.) </p> <p> @@ -651,12 +770,12 @@ return to what that instance was doing before the new intent arrived. <p> For more on launch modes, see -<a href="{@docRoot}guide/topics/manifest/manifest.html">The +<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml File</a> </p> -<h3><a name="clearstack"></a>Clearing the stack</h3> +<h3 id="clearstack">Clearing the stack</h3> <p> If the user leaves a task for a long time, the system clears the task of all @@ -676,7 +795,7 @@ control this behavior and modify it: <dt>The {@code alwaysRetainTaskState} attribute</dt> <dd>If this attribute is set to "{@code true}" in the root activity of a task, the default behavior just described does not happen. -Activities are retained in the stack even after a long period.</dd> +The task retains all activities in its stack even after a long period.</dd> <dt>The {@code clearTaskOnLaunch} attribute</dt> <dd>If this attribute is set to "{@code true}" in the root activity of a task, @@ -690,7 +809,7 @@ initial state, even after a momentary absence.</dd> single activity, not an entire task. And it can cause any activity to go away, including the root activity. When it's set to "{@code true}", the activity remains part of the task only for the current session. If the user -leaves and then relaunches the task, it no longer is present.</dd> +leaves and then returns to the task, it no longer is present.</dd> </dl> <p> @@ -700,7 +819,11 @@ android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_CLEAR_TOP}</code> flag, and the target task already has an instance of the type of activity that should handle the intent in its stack, all activities above that instance are cleared away so that it stands at the top of the stack and can respond -to the intent. +to the intent. +If the launch mode of the designated activity is "{@code standard}", it too +will be removed from the stack, and a new instance will be launched to handle +the incoming intent. That's because a new instance is always created for +a new intent when the launch mode is "{@code standard}". </p> <p> @@ -711,7 +834,7 @@ a position where it can respond to the intent. </p> -<h3><a name="starttask"></a>Starting tasks</h3> +<h3 id="starttask">Starting tasks</h3> <p> An activity is set up as the entry point for a task by giving it @@ -731,7 +854,7 @@ and then come back to it later. For this reason, the two launch modes that mark activities as always initiating a task, "{@code singleTask}" and "{@code singleInstance}", should be used only when the activity has a {@code MAIN} and {@code LAUNCHER} filter. -Imagine, for example, what could happen if the filter is missing. +Imagine, for example, what could happen if the filter is missing: An intent launches a "{@code singleTask}" activity, initiating a new task, and the user spends some time working in that task. The user then presses the HOME key. The task is now ordered behind and obscured by the home @@ -760,7 +883,7 @@ See <a href="#clearstack">Clearing the stack</a>, earlier. </p> -<h2><a name="procthread"></a>Processes and Threads</h2> +<h2 id="procthread">Processes and Threads</h2> <p> When the first of an application's components needs to be run, Android @@ -769,12 +892,15 @@ all components of the application run in that process and thread. </p> <p> -However, you can arrange for components to run in other processes as well as -spawn additional threads: +However, you can arrange for components to run in other processes, and you +can spawn additional threads for any process. </p> -<ul> -<li>The process where a component runs is controlled by the manifest file. + +<h3 id="procs">Processes</h3> + +<p> +The process where a component runs is controlled by the manifest file. The component elements — {@code <activity>}, {@code <service>}, {@code <receiver>}, and {@code <provider>} — each have a {@code process} attribute that can specify a process @@ -784,26 +910,27 @@ while others do not. They can also be set so that components of different applications run in the same process — provided that the applications share the same Linux user ID and are signed by the same authorities. The {@code <application>} element also has a {@code process} attribute, -for setting a default value that applies to all components.</li> - -<li><p>Threads are created in code using standard Java {@link java.lang.Thread} -objects. Android provides a number of convenience classes for managing threads -— {@link android.os.Looper} for running a message loop within a thread, -{@link android.os.Handler} for processing messages, and -{@link android.os.HandlerThread} for setting up a thread with a message loop.</p> +for setting a default value that applies to all components. +</p> <p> -Even though you may confine your application to a single process, there may be -times when you will need to spawn a thread to do some background work. Since the -user interface must always be quick to respond to user actions, the -thread that hosts an activity should not also host time-consuming operations like -network downloads, or anything else that may not be completed quickly. -</p></li> -</ul> +All components are instantiated in the main thread of the specified +process, and system calls to the component are dispatched from that +thread. Separate threads are not created for each instance. Consequently, +methods that respond to those calls — methods like +<code>{@link android.view.View#onKeyDown View.onKeyDown()}</code> that report +user actions and the lifecycle notifications discussed later in the +<a href="#lcycles">Component Lifecycles</a> section — always run in the +main thread of the process. This means +that no component should perform long or blocking operations (such as networking +operations or computation loops) when called by the system, since this will block +any other components also in the process. You can spawn separate threads for +long operations, as discussed under <a href="#threads">Threads</a>, next. +</p> <p> Android may decide to shut down a process at some point, when memory is -low and required by other applications that are more immediately serving +low and required by other processes that are more immediately serving the user. Application components running in the process are consequently destroyed. A process is restarted for those components when there's again work for them to do. @@ -816,17 +943,176 @@ with activities that are no longer visible on screen than a process with visible activities. The decision whether to terminate a process, therefore, depends on the state of the components running in that process. Those states are the subject of -the next section, <a href="#lcycles">Lifecycles</a>. +a later section, <a href="#lcycles">Component Lifecycles</a>. +</p> + + +<h3 id="threads">Threads</h3> + +<p> +Even though you may confine your application to a single process, there will +likely be times when you will need to spawn a thread to do some background +work. Since the user interface must always be quick to respond to user actions, +the thread that hosts an activity should not also host time-consuming operations +like network downloads. Anything that may not be completed quickly should be +assigned to a different thread. +</p> + +<p> +Threads are created in code using standard Java {@link java.lang.Thread} +objects. Android provides a number of convenience classes for managing +threads — {@link android.os.Looper} for running a message loop within +a thread, {@link android.os.Handler} for processing messages, and +{@link android.os.HandlerThread} for setting up a thread with a message loop. </p> -<h2><a name="lcycles"></a>Lifecycles</h2> +<h3 id="rpc">Remote procedure calls</h3> + +<p> +Android has a lightweight mechanism for remote procedure calls (RPCs) +— where a method is called locally, but executed remotely (in another +process), with any result returned back to the caller. +This entails decomposing the method call and all its attendant data to a +level the operating system can understand, transmitting it from the local +process and address space to the remote process and address space, and +reassembling and reenacting the call there. Return values have to be +transmitted in the opposite direction. Android provides all the code +to do that work, so that you can concentrate on defining and implementing +the RPC interface itself. +</p> + +<p> +An RPC interface can include only methods. +All methods are executed synchronously (the local method blocks until the +remote method finishes), even if there is no return value. +</p> + +<p> +In brief, the mechanism works as follows: You'd begin by declaring the +RPC interface you want to implement using a simple IDL (interface definition +language). From that declaration, the +<code><a href="{@docRoot}guide/developing/tools/aidl.html">aidl</a></code> +tool generates a Java interface definition that must be made available to +both the local and the remote process. It contains two inner class, as shown +in the following diagram: +</p> + +<p style="margin-left: 2em"> +<img src="{@docRoot}images/binder_rpc.png" alt="RPC mechanism." border="0" /> +</p> + +<p> +The inner classes have all the code needed to administer remote procedure +calls for the interface you declared with the IDL. +Both inner classes implement the {@link android.os.IBinder} +interface. One of them is used locally and internally by the system; +the code you write can ignore it. +The other, called Stub, extends the {@link android.os.Binder} +class. In addition to internal code for effectuating the IPC calls, it +contains declarations for the methods in the RPC interface you declared. +You would subclass Stub to implement those methods, as indicated in the +diagram. +</p> + +<p> +Typically, the remote process would be managed by a service (because a +service can inform the system about the process and its connections to +other processes). It would have both the interface file generated by +the {@code aidl} tool and the Stub subclass implementing the +RPC methods. Clients of the service would have only the interface file +generated by the {@code aidl} tool. +</p> + +<p> +Here's how a connection between a service and its clients is set up: +</p> + +<ul> +<li>Clients of the service (on the local side) would implement +<code>{@link android.content.ServiceConnection#onServiceConnected +onServiceConnected()}</code> and +<code>{@link android.content.ServiceConnection#onServiceDisconnected +onServiceDisconnected()}</code> methods so they can be notified +when a successful connection to the remote service is established, and +when it goes away. They would then call +<code>{@link android.content.Context#bindService bindService()}</code> +to set up the connection. +</li> + +<li> +The service's <code>{@link android.app.Service#onBind onBind()}</code> +method would be implemented to either accept or reject the connection, +depending on the intent it receives (the intent passed to +{@code bindService()}). If the connection is accepted, it returns +an instance of the Stub subclass. +</li> + +<li>If the service accepts the connection, Android calls the +client's {@code onServiceConnected()} method and passes it an IBinder +object, a proxy for the Stub subclass managed by the service. Through +the proxy, the client can make calls on the remote service. +</li> +</ul> + +<p> +This brief description omits some details of the RPC mechanism. For more +information, see +<a href="{@docRoot}guide/developing/tools/aidl.html">Designing a Remote +Interface Using AIDL</a> and the {@link android.os.IBinder IBinder} class +description. +</p> + + +<h3 id="tsafe">Thread-safe methods</h3> + +<p> +In a few contexts, the methods you implement may be called from more +than one thread, and therefore must be written to be thread-safe. +</p> + +<p> +This is primarily true for methods that can be called remotely — +as in the RPC mechanism discussed in the previous section. +When a call on a method implemented in an IBinder object originates +in the same process as the IBinder, the method is executed in the +caller's thread. However, when the call originates in another process, +the method is executed in a thread chosen from a pool of threads that +Android maintains in the same process as the IBinder; it's not executed +in the main thread of the process. For example, whereas a service's +{@code onBind()} method would be called from the main thread of the +service's process, methods implemented in the object that {@code onBind()} +returns (for example, a Stub subclass that implements RPC methods) would +be called from threads in the pool. +Since services can have more than one client, more than one pool thread +can engage the same IBinder method at the same time. IBinder methods +must, therefore, be implemented to be thread-safe. +</p> + +<p> +Similarly, a content provider can receive data requests that originate in +other processes. Although the ContentResolver and ContentProvider classes +hide the details of how the interprocess communication is managed, +ContentProvider methods that respond to those requests — the methods +<code>{@link android.content.ContentProvider#query query()}</code>, +<code>{@link android.content.ContentProvider#insert insert()}</code>, +<code>{@link android.content.ContentProvider#delete delete()}</code>, +<code>{@link android.content.ContentProvider#update update()}</code>, and +<code>{@link android.content.ContentProvider#getType getType()}</code> +— are called from a pool of threads in the content provider's +process, not the main thread of the process. Since these methods +may be called from any number of threads at the same time, they too must +be implemented to be thread-safe. +</p> + + +<h2 id="lcycles">Component Lifecycles</h2> <p> Application components have a lifecycle — a beginning when Android instantiates them to respond to intents through to an end when the instances are destroyed. In between, they may sometimes be active -or inactive, or, in the case of activities, visible to the user or +or inactive,or, in the case of activities, visible to the user or invisible. This section discusses the lifecycles of activities, services, and broadcast receivers — including the states that they can be in during their lifetimes, the methods that notify you of transitions @@ -835,7 +1121,7 @@ the process hosting them might be terminated and the instances destroyed. </p> -<h3><a name="actlife"></a>Activity lifecycle</h3> +<h3 id="actlife">Activity lifecycle</h3> <p>An activity has essentially three states:</p> @@ -864,12 +1150,10 @@ method), or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state. </p> - -<h4>Lifecycle methods</h4> - <p> As an activity transitions from state to state, it is notified of the change by calls to the following protected methods: +</p> <p style="margin-left: 2em">{@code void onCreate(Bundle <i>savedInstanceState</i>)} <br/>{@code void onStart()} @@ -881,9 +1165,9 @@ by calls to the following protected methods: <p> All of these methods are hooks that you can override to do appropriate work -when the state changes. -All activities must implement <code>{@link android.app.Activity#onCreate -onCreate()}</code> to do initial setup when the activity is first instantiated. +when the state changes. All activities must implement +<code>{@link android.app.Activity#onCreate onCreate()}</code> to do the +initial setup when the object is first instantiated. Many will also implement <code>{@link android.app.Activity#onPause onPause()}</code> to commit data changes and otherwise prepare to stop interacting with the user. </p> @@ -950,7 +1234,7 @@ can be in. The square rectangles represent the callback methods you can impleme to perform operations when the activity transitions between states. <p> -<p><img src="{@docRoot}images/activity_lifecycle.png" +<p style="margin-left: 2em"><img src="{@docRoot}images/activity_lifecycle.png" alt="State diagram for an Android activity lifecycle." border="0" /></p> <p> @@ -1084,7 +1368,7 @@ extreme and dire circumstances when there is no other recourse. </p> -<h4><a name="actstate"></a>Saving activity state</h4> +<h4 id="actstate">Saving activity state</h4> <p> When the system, rather than the user, shuts down an activity to conserve @@ -1118,14 +1402,38 @@ return to the activity, so there's no reason to save its state. </p> <p> -Because {@code onSaveInstanceState()} is not always called, you -should use it only to record the transient state of the activity, -not to store persistent data. Use {@code onPause()} for that purpose -instead. +Because {@code onSaveInstanceState()} is not always called, you should +use it only to record the transient state of the activity, not to store +persistent data. Use {@code onPause()} for that purpose instead. +</p> + + +<h4 id="coordact">Coordinating activities</h4> + +<p> +When one activity starts another, they both experience lifecycle +transitions. One pauses and may stop, while the other starts up. +On occasion, you may need to coordinate these activities, one with +the other. +</p> + +<p> +The order of lifecycle callbacks is well defined, +particularly when the two activities are in the same process: </p> +<ol> +<li>The current activity's {@code onPause()} method is called.</li> + +<li>Next, the starting activity's {@code onCreate()}, {@code onStart()}, +and {@code onResume()} methods are called in sequence.</li> + +<li>Then, if the starting activity is no longer visible +on screen, its {@code onStop()} method is called.</li> +</ol> + -<h3><a name="servlife"></a>Service lifecycle</h3> +<h3 id="servlife">Service lifecycle</h3> <p> A service can be used in two ways: @@ -1243,11 +1551,11 @@ no matter how it's started, can potentially allow clients to bind to it, so any service may receive {@code onBind()} and {@code onUnbind()} calls. </p> -<p><img src="{@docRoot}images/service_lifecycle.png" +<p style="margin-left: 2em"><img src="{@docRoot}images/service_lifecycle.png" alt="State diagram for Service callbacks." border="0" /></p> -<h3><a name="broadlife"></a>Broadcast receiver lifecycle</h3> +<h3 id="broadlife">Broadcast receiver lifecycle</h3> <p> A broadcast receiver has single callback method: @@ -1286,15 +1594,16 @@ The next section has more on the vulnerability of processes to being killed. </p> -<h3><a name="proclife"></a>Processes and lifecycles</h3> +<h3 id="proclife">Processes and lifecycles</h3> <p>The Android system tries to maintain an application process for as long as possible, but eventually it will need to remove old processes when memory runs low. To determine which processes to keep and which to kill, Android places each process into an "importance hierarchy" based on the -components running in it and the state of those components. There are -five levels in the hierarchy. The following list presents them in order -of importance: +components running in it and the state of those components. Processes +with the lowest importance are eliminated first, then those with the next +lowest, and so on. There are five levels in the hierarchy. The following +list presents them in order of importance: </p> <ol> @@ -1348,16 +1657,15 @@ A visible process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running. </p></li> -<li><p>A <b>service process</b> is one that is running a service that has -been started with the +<li><p>A <b>service process</b> is one that is running a service that +has been started with the <code>{@link android.content.Context#startService startService()}</code> -method. Although service processes are not directly tied to anything the +method and that does not fall into either of the two higher categories. +Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing an mp3 in the background or downloading data on the network), so the system keeps them running unless there's not enough -memory to retain them along with all foreground and visible processes. -(Note that a service can be ranked higher than this by virtue of being -bound to a visible or foreground activity). +memory to retain them along with all foreground and visible processes. </p></li> <li><p>A <b>background process</b> is one holding an activity @@ -1365,8 +1673,8 @@ that's not currently visible to the user (the Activity object's <code>{@link android.app.Activity#onStop onStop()}</code> method has been called). These processes have no direct impact on the user experience, and can be killed at any time to reclaim memory for a foreground, visible, or service process. -Usually there are many background processes running, -so they are kept in an LRU list to ensure that the process with the activity that +Usually there are many background processes running, so they are kept in an +LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and captures its current state, killing its process will not have a deleterious effect on the user experience. diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd index 822c66f..a72962e 100644 --- a/docs/html/guide/topics/graphics/2d-graphics.jd +++ b/docs/html/guide/topics/graphics/2d-graphics.jd @@ -87,6 +87,13 @@ protected void onCreate(Bundle savedInstanceState) { To do so, create a Drawable from the resource like so: <pre>Drawable myImage = Resources.getDrawable(R.drawable.my_image);</pre> +<p class="caution"><strong>Caution:</strong> Each unique resource in your project can maintain only one +state, no matter how many different objects you may instantiate for it. For example, if you instantiate two +Drawable objects from the same image resource, then change a property (such as the alpha) for one of the +Drawables, then it will also affect the other. So when dealing with multiple instances of an image resource, +instead of directly transforming the Drawable, you should perform a <a href="#tween-animation">tween animation</a>.</p> + + <h4>Example XML</h4> <p>The XML snippet below shows how to add a resource Drawable to an {@link android.widget.ImageView} in the XML layout (with some red tint just for fun). @@ -103,8 +110,8 @@ To do so, create a Drawable from the resource like so: <h3 id="drawables-from-xml">Creating from resource XML</h3> -<p>By now, you should be familiar with Android's principles of -<a href="{@docRoot}guide/topics/views/index.html">Views and Layout</a>. Hence, you understand the power +<p>By now, you should be familiar with Android's principles of developing a +<a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>. Hence, you understand the power and flexibility inherent in defining objects in XML. This philosophy caries over from Views to Drawables. If there is a Drawable object that you'd like to create, which is not initially dependent on variables defined by your applicaton code or user interaction, then defining the Drawable in XML is a good option. @@ -309,15 +316,28 @@ stretches to accommodate it. <h2 id="tween-animation">Tween Animation</h2> -<p>A tweened animation can perform a series of simple transformations (position, size, rotation, and transparency) on +<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 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.</p> +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>The animation is achieved with a sequence of animation instructions, defined in either XML or code. +<p>A sequence of animation instructions defines the twen animation, defined by either XML or Android code. Like defining a layout, an XML file is recommended because it's more readable, reusable, and swappable -than hard-coding it. In the example below, we use XML. (To define an animation in code, refer to the +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, @@ -389,22 +409,23 @@ spaceshipImage.startAnimation(hyperspaceJumpAnimation); <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> +<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 the discussion on animation in the <a href="{@docRoot}guide/topics/resources/available-resources.html#animation">Available Resources</a>.</p> -<p class="note"><strong>Note:</strong> Animations are drawn in the area designated for the View at the start of -the animation; this area does not change to accommodate size or movement, so if your animation moves or expands -outside the original boundaries of your object, it will be clipped to the size of the original View, even if -the object's LayoutParams are set to WRAP_CONTENT (the object will not resize to accommodate moving or -expanding/shrinking animations).</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 accomodate 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.</p> +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 @@ -454,6 +475,6 @@ called during the <code>onCreate()</code> method of your Activity, because the A 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> +your Activity, which will get called when Android brings your window into focus.</p> diff --git a/docs/html/guide/topics/graphics/index.jd b/docs/html/guide/topics/graphics/index.jd index 388acc9..bc2a8bf 100644 --- a/docs/html/guide/topics/graphics/index.jd +++ b/docs/html/guide/topics/graphics/index.jd @@ -1,21 +1,203 @@ -page.title=2D and 3D Graphics +page.title=Graphics @jd:body - +<div id="qv-wrapper"> + <div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#options">Consider your Options</a></li> + <li><a href="#draw-to-view">Simple Graphics Inside a View</a></li> + <li><a href="#draw-with-canvas">Draw with a Canvas</a> + <ol> + <li><a href="#on-view">On a View</a></li> + <li><a href="#on-surfaceview">On a SurfaceView</a></li> + </ol> + </li> + </ol> + </div> +</div> <p>Android graphics are powered by a custom 2D graphics library and OpenGL ES 1.0 -for 3D graphics.</p> - -<h2>2D Graphics</h2> -<p>Android offers a custom 2D graphics library for drawing shapes and images.</p> -<p>The {@link android.graphics} and {@link android.graphics.drawable} -packages are where you'll find the classes used for drawing in two-dimensions. -For common drawing tasks, though, the {@link android.graphics.drawable} package -is where you'll find what you need.</p> -<p>For an introduction to drawing shapes and images, read the -<a href="2d-graphics.html">2D Graphics</a> document.</p> - - -<h2>3D with OpenGL</h2> -<p>High performance 3D graphic utilities are provided on Android with the OpenGL ES API. -You'll find the OpenGL APIs in the {@link android.opengl} package. -Read more about <a href="opengl.html">3D with OpenGL</a>.</p>
\ No newline at end of file +for high performance 3D graphics. The most common 2D graphics APIs can be found in the +{@link android.graphics.drawable drawable package}. OpenGL APIs are available +from the Khronos {@link javax.microedition.khronos.opengles OpenGL ES package}, +plus some Android {@link android.opengl OpenGL utilities}.</p> + +<p>When starting a project, it's important to consider exactly what your graphical demands will be. +Varying graphical tasks are best accomplished with varying techniques. For example, graphics and animations +for a rather static application should be implemented much differently than graphics and animations +for an interactive game or 3D rendering.</p> + +<p>Here, we'll discuss a few of the options you have for drawing graphics on Android, +and which tasks they're best suited for.</p> + +<p>If you're specifically looking for information on drawing 3D graphics, this page won't +help a lot. However, the information below, on <a href="#drawing-with-canvas">Drawing with a Canvas</a> +(and the section on SurfaceView), +will give you a quick idea of how you should draw to the View hierarchy. For more information +on Android's 3D graphic utilities (provided by the OpenGL ES API), +read <a href="opengl.html">3D with OpenGL</a> and refer to other OpenGL documentation.</p> + + +<h2 id="options">Consider your Options</h2> + +<p>When drawing 2D graphics, you'll typically do so in one of two ways:</p> +<ol type="a"> + <li>Draw your graphics or animations into a View object from your layout. In this manner, + the drawing (and any animation) of your graphics is handled by the system's + normal View hierarchy drawing process — you simply define the graphics to go inside the View.</li> + <li>Draw your graphics directly to a Canvas. This way, you personally call the appropriate class's + <code>draw()</code> method (passing it your Canvas), or one of the Canvas <code>draw...()</code> methods (like + <code>{@link android.graphics.Canvas#drawPicture(Picture,Rect) drawPicture()}</code>). In doing so, you are also in + control of any animation.</li> +</ol> + +<p>Option "a," drawing to a View, is your best choice when you want to draw simple graphics that do not +need to change dynamically and are not part of a performance-intensive game. For example, you should +draw your graphics into a View when you want to display a static graphic or predefined animation, within +an otherwise static application. Read <a href="#draw-to-view">Simple Graphics Inside a View</a>.</li> + +<p>Option "b," drawing to a Canvas, is better when you're application needs to regularly re-draw itself. +Basically, any video game should be drawing to the Canvas on its own. However, there's more than +one way to do this: </p> +<ul> + <li>In the same thread as your UI Activity, wherein you create a custom View component in + your layout, call <code>{@link android.view.View#invalidate()}</code> and then handle the + <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> callback..</li> + <li>Or, in a separate thread, wherein you manage a {@link android.view.SurfaceView} and + perform draws to the Canvas as fast as your thread is capable + (you do not need to request <code>invalidate()</code>).</li> +</ul> +<p>...Begin by reading <a href="#draw-with-canvas">Draw with a Canvas</a>.</p> + +<h2 id="draw-to-view">Simple Graphics Inside a View</h2> + +<p>If you'll be drawing some simple graphics (images, shapes, colors, pre-defined animations, etc.), +then you should probably just draw to the background of a View or +to the content of an {@link android.widget.ImageView} in your layout. +In this case, you can skip the rest of this document and learn how to +draw graphics and animations in the <a href="2d-graphics.html">2D Graphics</a> document. +</p> + + +<h2 id="draw-with-canvas">Draw with a Canvas</h2> + +<p>When you're writing an application in which you would like to perform specialized drawing +and/or control the animation of graphics, +you should do so by drawing through a {@link android.graphics.Canvas}. A Canvas works for you as +a pretense, or interface, to the actual surface upon which your graphics will be drawn — it +holds all of your "draw" calls. Via the Canvas, your drawing is actually performed upon an +underlying {@link android.graphics.Bitmap}, which is placed into the window.</p> + +<p>In the event that you're drawing within the <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> +callback method, the Canvas is provided for you and you need only place your drawing calls upon it. +You can also acquire a Canvas from <code>{@link android.view.SurfaceHolder#lockCanvas() SurfaceHolder.lockCanvas()}</code>, +when dealing with a SurfaceView object. (Both of these scenarios are discussed in the following sections.) +However, if you need to create a new Canvas, then you must define the {@link android.graphics.Bitmap} +upon which drawing will actually be performed. The Bitmap is always required for a Canvas. You can set up +a new Canvas like this:</p> +<pre> +Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); +Canvas c = new Canvas(b); +</pre> + +<p>Now your Canvas will draw onto the defined Bitmap. After drawing upon it with the Canvas, you can then carry your +Bitmap to another Canvas with one of the <code>{@link android.graphics.Canvas#drawBitmap(Bitmap,Matrix,Paint) +Canvas.drawBitmap(Bitmap,...)}</code> methods. It's recommended that you ultimately draw your final +graphics through a Canvas offered to you +by <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code> or +<code>{@link android.view.SurfaceHolder#lockCanvas() SurfaceHolder.lockCanvas()}</code> (see the following sections).</p> + +<p>The {@link android.graphics.Canvas} class has its own set of drawing methods that you can use, +like <code>drawBitmap(...)</code>, <code>drawRect(...)</code>, <code>drawText(...)</code>, and many more. +Other classes that you might use also have <code>draw()</code> methods. For example, you'll probably +have some {@link android.graphics.drawable.Drawable} objects that you want to put on the Canvas. Drawable +has its own <code>{@link android.graphics.drawable.Drawable#draw(Canvas) draw()}</code> method +that takes your Canvas as an arguement.</p> + + +<h3 id="on-view">On a View</h3> + +<p>If you're application does not require a significant amount of processing or +frame-rate speed (perhaps for a chess game, a snake game, +or another slowly-animated application), then you should consider creating a custom View component +and drawing with a Canvas in <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code>. +The most convenient aspect of doing so is that the Android framework will +provide you with a pre-defined Canvas to which you will place your drawing calls.</p> + +<p>To start, extend the {@link android.view.View} class (or descendent thereof) and define +the <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> callback method. This method will be called by the Android +framework to request that your View draw itself. This is where you will perform all your calls +to draw through the {@link android.graphics.Canvas}, which is passed to you through the <code>onDraw()</code> callback.</p> + +<p>The Android framework will only call <code>onDraw()</code> as necessary. Each time that +your application is prepared to be drawn, you must request your View be invalidated by calling +<code>{@link android.view.View#invalidate()}</code>. This indicates that you'd like your View to be drawn and +Android will then call your <code>onDraw()</code> method (though is not guaranteed that the callback will +be instantaneous). </p> + +<p>Inside your View component's <code>onDraw()</code>, use the Canvas given to you for all your drawing, +using various <code>Canvas.draw...()</code> methods, or other class <code>draw()</code> methods that +take your Canvas as an argument. Once your <code>onDraw()</code> is complete, the Android framework will +use your Canvas to draw a Bitmap handled by the system.</p> + +<p class="note"><strong>Note: </strong> In order to request an invalidate from a thread other than your main +Activity's thread, you must call <code>{@link android.view.View#postInvalidate()}</code>.</p> + +<p>Also read <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a> +for a guide to extending a View class, and <a href="2d-graphics.html">2D Graphics: Drawables</a> for +information on using Drawable objects like images from your resources and other primitive shapes.</p> + +<p>For a sample application, see the Snake game, in the SDK samples folder: +<code><your-sdk-directory>/samples/Snake/</code>.</p> + +<h3 id="on-surfaceview">On a SurfaceView</h3> + +<p>The {@link android.view.SurfaceView} is a special subclass of View that offers a dedicated +drawing surface within the View hierarchy. The aim is to offer this drawing surface to +an application's secondary thread, so that the application isn't required +to wait until the system's View hierarchy is ready to draw. Instead, a secondary thread +that has reference to a SurfaceView can draw to its own Canvas at its own pace.</p> + +<p>To begin, you need to create a new class that extends {@link android.view.SurfaceView}. The class should also +implement {@link android.view.SurfaceHolder.Callback}. This subclass is an interface that will notify you +with information about the underlying {@link android.view.Surface}, such as when it is created, changed, or destroyed. +These events are important so that you know when you can start drawing, whether you need +to make adjustments based on new surface properties, and when to stop drawing and potentially +kill some tasks. Inside your SurfaceView class is also a good place to define your secondary Thread class, which will +perform all the drawing procedures to your Canvas.</p> + +<p>Instead of handling the Surface object directly, you should handle it via +a {@link android.view.SurfaceHolder}. So, when your SurfaceView is initialized, get the SurfaceHolder by calling +<code>{@link android.view.SurfaceView#getHolder()}</code>. You should then notify the SurfaceHolder that you'd +like to receive SurfaceHolder callbacks (from {@link android.view.SurfaceHolder.Callback}) by calling +{@link android.view.SurfaceHolder#addCallback(SurfaceHolder.Callback) addCallback()} +(pass it <var>this</var>). Then override each of the +{@link android.view.SurfaceHolder.Callback} methods inside your SurfaceView class.</p> + +<p>In order to draw to the Surface Canvas from within your second thread, you must pass the thread your SurfaceHandler +and retrieve the Canvas with <code>{@link android.view.SurfaceHolder#lockCanvas() lockCanvas()}</code>. +You can now take the Canvas given to you by the SurfaceHolder and do your necessary drawing upon it. +Once you're done drawing with the Canvas, call +<code>{@link android.view.SurfaceHolder#unlockCanvasAndPost(Canvas) unlockCanvasAndPost()}</code>, passing it +your Canvas object. The Surface will now draw the Canvas as you left it. Perform this sequence of locking and +unlocking the canvas each time you want to redraw.</p> + +<p class="note"><strong>Note:</strong> On each pass you retrieve the Canvas from the SurfaceHolder, +the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the +entire surface. For example, you can clear the previous state of the Canvas by filling in a color +with <code>{@link android.graphics.Canvas#drawColor(int) drawColor()}</code> or setting a background image +with <code>{@link android.graphics.Canvas#drawBitmap(Bitmap,Rect,RectF,Paint) drawBitmap()}</code>. Otherwise, +you will see traces of the drawings you previously performed.</p> + + +<p>For a sample application, see the Lunar Landar game, in the SDK samples folder: +<code><your-sdk-directory>/samples/LunarLander/</code>. Or, +browse the source in the <a href="{@docRoot}guide/samples/index.html">Sample Code</a> section.</p> + + + + + + + + diff --git a/docs/html/guide/topics/location/geo/mapkey.jd b/docs/html/guide/topics/location/geo/mapkey.jd index 110876f..9aa824c 100644 --- a/docs/html/guide/topics/location/geo/mapkey.jd +++ b/docs/html/guide/topics/location/geo/mapkey.jd @@ -1,28 +1,210 @@ -page.title=Obtaining a MapView API Key +page.title=Obtaining a Maps API Key @jd:body -<p>{@link-fixme com.google.android.maps.MapView} is a very useful class that lets you easily integrate Google Maps into your application. It provides built-in map downloading, rendering, and caching, as well as a variety of display options and controls. It provides a wrapper around the Google Maps API that lets your application request and manipulate Google Maps data through class methods, and it lets you work with Maps data as you would other types of Views. </p> +<div class="sidebox"><p>To register for a Maps API Key, read this document and then go to the <a href="http://code.google.com/android/maps-api-signup.html">Android Maps API Key Signup</a> page.</p> -<p>Because MapView gives you access to Google Maps data, you need to register your application with the Google Maps service and agree to the applicable Terms of Service, before your MapView will be able to obtain data from Google Maps. This will apply whether you are developing your application on the emulator or preparing your application for deployment to mobile devices. </p> +</div> -<p>Registering your application is simple, and has two parts: </p> +<p>com.google.android.maps.MapView is a very useful class that lets you easily integrate Google Maps into your application. It provides built-in map downloading, rendering, and caching of Maps tiles, as well as a variety of display options and controls. It provides a wrapper around the Google Maps API that lets your application request and manipulate Google Maps data through class methods, and it lets you work with Maps data as you would other types of Views. </p> + +<p>Because MapView gives you access to Google Maps data, you need to register with the Google Maps service and agree to the applicable Terms of Service before your MapView will be able to obtain data from Google Maps. This will apply whether you are developing your application on the emulator or preparing your application for deployment to mobile devices. </p> + +<p>Registering for a Maps API Key is simple, free, and has two parts: </p> <ol> -<li>Registering a public key fingerprint from the certificate that you will use to sign the .apk. The registration service then provides you a Maps API Key that is associated with your application's signer certificate. </li> -<li>Adding the Maps API Key to a special attribute of the MapView element — <code>android:apiKey</code>. You can use the same Maps API Key for any MapView in any application, provided that the application's .apk is signed with the certificate whose fingerprint you registered with the service. </li> +<li>Registering the MD5 fingerprint of the certificate that you will use to sign your application. The Maps registration service then provides you a Maps API Key that is associated with your application's signer certificate. </li> +<li>Adding a reference to the Maps API Key in each MapView, whether declared in XML or instantiated directly from code. You can use the same Maps API Key for any MapView in any Android application, provided that the application is signed with the certificate whose fingerprint you registered with the service. </li> </ol> -<p>Once you have registered your application as described above, your MapView will be able to retrieve data from the Google Maps servers. </p> +<p>During registration, you also need to agree to the Maps API Terms of Service, which describe how your application can use the Maps data. In general, the terms of service are permissive and place few restrictions on how you can use the data. For example, the terms allow you to build "friend finder" type applications. </p> + +<p>The sections below describe how to obtain your Maps API Key and how to reference it from your MapView elements. </p> + +<ul> +<li><a href="#overview">Overview</a></li> +<li><a href="#getfingerprint">Getting the MD5 Fingerprint of Your Signing Certificate</a></li> +<li><a href="#getdebugfingerprint">Getting the MD5 Fingerprint of the SDK Debug Certificate</a></li> +<li><a href="#registering">Registering the Certificate Fingerprint with the Google Maps Service</a></li> +<li><a href="#addingkey">Adding the Maps API Key to your Application</a></li> +<li><a href="#finalsteps">Final Steps to Enable MapView Elements</a></li> +</ul> + +<h2 id="overview">Overview</h2> + +<p>MapView objects are views that display Maps tiles downloaded from the Google Maps service. To ensure that applications use Maps data in an appropriate manner, the Google Maps service requires application developers to register with the service, agreeing to the Terms of Service and supplying an MD5 fingerprint of the certificate(s) that they will use to sign applications. For each registered certificate fingerprint, the service then provides the developer with a Maps API Key — an alphanumeric string that uniquely identifies the certificate and developer registered with the service. </p> + +<p>The Google Maps service also requires that each MapView identify itself to the service using a Maps API Key. Before providing Maps tiles to a MapView, the service checks the Maps API Key supplied by the MapView to ensure that it:</p> +<ul> +<li>References a certificate/developer registered with the service, and </li> +<li>References a certificate that matches the certificate with which the application (containing the MapView) was signed. </li> +</ul> + +<p>Unless both conditions are met, the service does not provide Maps tiles to the MapView. </p> + +<p>Each MapView object in your application must reference a Maps API Key. Since the Key is associated with a certificate, all Mapview elements in an application should reference the same Key. Going a step further, all MapView elements in all applications that you sign with the same certificate should reference the same Key. </p> + +<p>On the other hand, you can register for multiple Maps API Keys, each being associated with a specific certificate. You would want to do this if, for example, you were developing several independent applications that you will sign using different certificates. In this case, note that all MapView elements in a given application can reference the same Maps API Key, but <em>must</em> reference the Key that is associated with the certificate used to sign the application. </p> + +<p>Because MapView elements must refer to a Maps API Key, you need to register your certificate and receive a Key before you can make use of MapView elements in your application. To make it easier for you to get started using MapView elements, you are welcome to register the debug certificate generated by the SDK tools and receive a temporary Maps API Key. The details of how to do that are given below. </p> + +<p>When you are preparing to release your application, however, note that you <em>must</em> sign your application with a suitable cryptographic key, rather than the SDK debug key. That means that you will also need to register your application's release certificate with the Google Maps service. After you've done so, you will receive a new Maps API Key that is uniquely associated with your release certificate. To enable the MapView elements in your application to work after release, you must remember to change the Maps API Key for all MapViews in your application so that they refer to the Key associated with your release certificate (rather than your debug certificate). </p> + +<p>To summarize, the important points to understand about MapViews and the Maps API Key are: </p> + +<ul> +<li>To display Maps data in a MapView, you need to register for a Maps API Key</li> +<li>Each Maps API Key is uniquely associated with a specific certificate, based on an MD5 fingerprint of the certificate </li> +<li>Each MapView must reference a Maps API Key, and the Key referenced must be registered to the certificate used to sign the application</li> +<li>All MapView elements in an application can reference the same Maps API Key</li> +<li>You can register multiple certificates under your developer identity</li> +<li>You can get a temporary Maps API Key based on your debug certificate, but before you publish your application, you must register for a new Key based on your release certificate and update references in your MapViews accordingly</li> +</ul> + +<h2 id="getfingerprint">Getting the MD5 Fingerprint of Your Signing Certificate</h2> + +<div class="sidebox"> +For more information about using Keytool and Jarsigner to sign your application, see <a href="{@docRoot}guide/publishing/app-signing.html">Signing Your Applications</a>. +</div> + +<p>To register for a Maps API Key, you need to provide an MD5 fingerprint of the certificate that you will use to sign your application. </p> + +<p>Before you visit the registration page, use Keytool to generate the fingerprint of the appropriate certificate. + +<p>First, determine which key you will use to sign your application at release and make sure of the path to the keystore that contains it.</p> + +<p>Next, run Keytool with the <code>-list</code> option, against the target keystore and key alias. The table below lists the options you should use.</p> + +<table> +<tr> +<th>Keytool Option</th> +<th>Description</th> +</tr> +<tr> +<td><code>-list</code></td><td>Print an MD5 fingerprint of a certificate.</td> +</tr> +<tr> +<td><code>-keystore <keystore-name>.keystore</code></td><td>The name of the keystore containing the target key.</td> +</tr> +<tr> +<td><code>-storepass <password></code></td><td><p>A password for the +keystore.</p><p>As a security precaution, do not include this option +in your command line unless you are working at a secure computer. +If not supplied, Keytool prompts you to enter the password. In this +way, your password is not stored in your shell history.</p></td> +</tr> +<tr> +<td><code>-alias <alias_name></code></td><td>The alias for the key for which to generate the MD5 certificate fingerprint.</td> +</tr> +<tr> +<td><code>-keypass <password></code></td><td><p>The password for the key.</p> +<p>As a security precaution, do not include this option +in your command line unless you are working at a secure computer. +If not supplied, Keytool prompts you to enter the password. In this +way, your password is not stored in your shell history.</p></td> +</tr> +</table> + +<p>Here's an example of a Keytool command that generates an MD5 certificate fingerprint for the key <code>alias_name</code> in the keystore <code>my-release-key.keystore</code>:</p> + +<pre>$ keytool -list -alias alias_name -keystore my-release-key.keystore</pre> + +<p>Keytool will prompt you to enter passwords for the keystore and key. As output of the command, Keytool prints the fingerprint to the shell. For example:</p> + +<pre>Certificate fingerprint (MD5): 94:1E:43:49:87:73:BB:E6:A6:88:D7:20:F1:8E:B5:98</pre> + +<p>Note that, if you happen to forget your Maps API Key, you can repeat the process described above and register the fingerprint again. The server will give you the same key for the specified certificate fingerprint.</p> + +<p>Once you have the fingerprint, you can go to the Maps API registration site, described next.</p> + +<h2 id="getdebugfingerprint">Getting the MD5 Fingerprint of the SDK Debug Certificate</h2> -<div class="special"> -<p>The MapView registration service is not yet active and Google Maps is not yet enforcing the Maps API Key requirement. The registration service will be activated soon, so that MapViews in any application deployed to a mobile device will require registration and a valid Maps API Key.</p> +<p>While you are developing and debugging your application, you will likely be +sigining your application in debug mode — that is, the SDK build tools +will automatically sign your application using the debug certificate. To let +your MapView elements properly display Maps data during this period, you should +obtain a temporary Maps API Key registered to the debug certificate. To do so, +you first need to get the MD5 fingerprint of the debug certificate. When +you are ready to release your application, you must register your release +certificate with the Google Maps service and obtain a new Maps API Key. You must +then change the MapView elements in your application to reference the new API +key. </p> -<p>As soon as the registration service becomes available, this page (<a href="http://code.google.com/android/toolbox/apis/mapkey.html">http://code.google.com/android/toolbox/apis/mapkey.html</a>) will be updated with details about how and where to register and how to add your Maps API Key to your application. </p> +<p>To generate an MD5 fingerprint of the debug certificate, first locate the debug keystore. The location at which the SDK tools create the default debug keystore varies by platform: </p> -<p>In the meantime, you can continue developing your MapView without registration, provided that you:</p> -<ol type="a"> -<li>Add the attribute "android:apiKey" to the MapView element in your layout XML, with any value. Or</li> -<li>Include an arbitrary string in the <code>apikey</code> parameter of the MapView constructor, if creating the MapView programmatically. </li> +<ul> +<li>Windows Vista: <code>C:\Users\<user>\AppData\Local\Android\debug.keystore</code></li> +<li>Windows XP: <code>C:\Documents and Settings\<user>\Local Settings\Application Data\Android\debug.keystore</code></li> +<li>OS X and Linux: <code>~/.android/debug.keystore</code></li> +</ul> + +<p>If you are using Eclipse/ADT and are unsure where the debug keystore is located, you can select <strong>Windows</strong> > <strong>Prefs</strong> > <strong>Android</strong> > <strong>Build</strong> to check the full path, which you can then paste into a file explorer to locate the directory containing the keystore.</p> + +<p>Once you have located the keystore, use this Keytool command to get the MD5 fingerprint of the debug certificate:</p> + +<pre>$ keytool -list -alias androiddebugkey \ +-keystore <path_to_debug_keystore>.keystore \ +-storepass android -keypass android</pre> + +<h2 id="registering">Registering the Certificate Fingerprint with the Google Maps Service</h2> + +<p>When you are ready to register for a Maps API Key, load this page in a browser: </p> + +<p><a href="http://code.google.com/android/maps-api-signup.html">http://code.google.com/android/maps-api-signup.html</a></p> + +<p>To register for a Maps API Key, follow these steps:</p> + +<ol> +<li>If you don't have a Google account, use the link on the page to set one up. </li> +<li>Read the Android Maps API Terms of Service carefully. If you agree to the terms, indicate so using the checkbox on the screen. </li> +<li>Paste the MD5 certificate fingerprint of the certificate that you are registering into the appropriate form field.</li> +<li>Click "Generate API Key"</li> </ol> -<p>When the Maps API Key checking is activated in the service, any MapViews that do not have a properly registered apiKey will stop working. The map data (tile images) of the MapView will never load (even if the device is on the network). In this case, go to the page linked above and read about how to register your certificate fingerprint and obtain a Maps API Key. </p> +<p>The server will handle your request, associating the fingerprint with your developer identity and generating a unique Maps API Key, then returning a results page that gives you your Key string. </p> + +<p>To use the Maps API Key string, copy and paste it into your code as described in the next section.</p> + +<h2 id="addingkey">Adding the Maps API Key to your Application</h2> + +<p>Once you've registered with the Google Maps service and have obtained a Maps API Key, you must add it to your application's MapView objects, so that the Maps server will allow them to download Maps tiles. </p> + +<p>For <code><MapView></code> elements declared in XML layout files, add the Maps API Key as the value of a special attribute — <code>android:apiKey</code>. For example: </li> + +<pre><com.google.android.maps.MapView + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:enabled="true" + android:clickable="true" + android:apiKey="example_Maps_ApiKey_String" + /></pre> +</li> + +<p>For MapView objects instantiated directly from code, pass the Maps API Key string as a parameter in the constructor. For example: </p> + +<pre>mMapView = new MapView(this, "example_Maps_ApiKey_String");</pre> + +<p>For more information about MapView, see the MapView class Documentation. </p> + +<h2 id="finalsteps">Final Steps to Enable MapView Elements</h2> + +<p>If you've added the Maps API Key to the MapViews in your application, here are the final steps to enable the MapView elements to run properly:</p> + +<ul> +<li>Make sure that you added a <code><uses-library></code> element referencing the external <code>com.google.android.maps</code> library. The element must be a child of the <code><application></code> element in the application's manifest. For example: + +<p><pre><manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.package.name"> + ... + <application android:name="MyApplication" > + <uses-library android:name="com.google.android.maps" /> + ... + </application></pre></p></li> + +<li>Sign your application with the certificate that corresponds to the Maps API Key referenced in your MapView elements. </li> + +</ul> + +<div class="special"><p>Note that, when you are ready to publish your application, you must get a Maps API Key that is based on the certificate that you will use to sign the application for release. You must then change the Maps API Key string referenced by all of your MapView elements, so that they reference the new Key. </p></div> + + + diff --git a/docs/html/guide/topics/location/index.jd b/docs/html/guide/topics/location/index.jd index eeaab39..53f1d29 100644 --- a/docs/html/guide/topics/location/index.jd +++ b/docs/html/guide/topics/location/index.jd @@ -95,7 +95,7 @@ MapView must extend {@link-fixme com.google.android.maps.MapActivity}. </p> <p>Also note that you must obtain a MapView API Key from the Google Maps service, before your MapView can load maps data. For more information, see -<a href="{@docRoot}guide/developing/mapkey.html">Obtaining a MapView API Key</a>.</p> +<a href="{@docRoot}guide/topics/location/geo/mapkey.html">Obtaining a MapView API Key</a>.</p> <p>Once you've created a MapView, you'll probably want to use {@link-fixme com.google.android.maps.MapView#getController()} to diff --git a/docs/html/guide/topics/resources/available-resources.jd b/docs/html/guide/topics/resources/available-resources.jd index 7ba9e52..2a6a6ac 100644 --- a/docs/html/guide/topics/resources/available-resources.jd +++ b/docs/html/guide/topics/resources/available-resources.jd @@ -853,7 +853,7 @@ of an <code><item></code> (to create a Sub Menu).</p> </dl> <p>For more discussion on how to create menus in XML and inflate them in your application, -read <a href="{@docRoot}guide/topics/views/menus.html">Creating Menus</a>.</p> +read <a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>.</p> @@ -877,7 +877,7 @@ the Android namespace "http://schemas.android.com/apk/res/android" defined in the root element.</p> <p>For a complete discussion on creating layouts, see the -<a href="{@docRoot}guide/topics/views/index.html">Views and Layout</a> topic.</p> +<a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> topic.</p> <p> <strong>Source file format:</strong> XML file requiring a <code><?xml version="1.0" encoding="utf-8"?></code> @@ -971,7 +971,7 @@ res/layout/<em>some_file</em>.xml.</p> <strong>Attributes exposed by all the superclasses of that element.</strong> For example, the TextView class extends the View class, so the <code><TextView></code> element supports all the attributes that the <code><View></code> element exposes — a long list, including <code>View_paddingBottom</code> and <code>View_scrollbars</code>. These too are used without the class name: <code><TextView android:paddingBottom="20" android:scrollbars="horizontal" /></code>. </li> <li> - <strong>Attributes of the object's {@link android.view.ViewGroup.LayoutParams} subclass.</strong> All View objects support a LayoutParams member (see <a href="{@docRoot}guide/topics/views/layout.html">LayoutParams in Implementing a UI</a>). To set properties on an element's LayoutParams member, the attribute to use is "android:layout_<em>layoutParamsProperty</em>". For example: <code>android:layout_gravity</code> for an object wrapped by a <code><LinearLayout></code> element. Remember that each LayoutParams subclass also supports inherited attributes. Attributes exposed by each subclass are given in the format <em>someLayoutParamsSubclass</em>_Layout_layout_<em>someproperty</em>. This defines an attribute "android:layout_<em>someproperty</em>". Here is an example of how Android documentation lists the properties of the {@link android.widget.LinearLayout.LayoutParams LinearLayout.LayoutParams} class: + <strong>Attributes of the object's {@link android.view.ViewGroup.LayoutParams} subclass.</strong> All View objects support a LayoutParams member (see <a href="{@docRoot}guide/topics/ui/declaring-layout.html#layout-params">Declaring Layout</a>). To set properties on an element's LayoutParams member, the attribute to use is "android:layout_<em>layoutParamsProperty</em>". For example: <code>android:layout_gravity</code> for an object wrapped by a <code><LinearLayout></code> element. Remember that each LayoutParams subclass also supports inherited attributes. Attributes exposed by each subclass are given in the format <em>someLayoutParamsSubclass</em>_Layout_layout_<em>someproperty</em>. This defines an attribute "android:layout_<em>someproperty</em>". Here is an example of how Android documentation lists the properties of the {@link android.widget.LinearLayout.LayoutParams LinearLayout.LayoutParams} class: </li> </ul> <ul> @@ -1032,7 +1032,7 @@ setContentView(R.layout.main_screen); However, layout elements can also represent repeating elements used as templates. </p> -<p>Also see <a href="{@docRoot}guide/topics/views/index.html">Views and Layout</a> for more information on layouts.</p> +<p>Also see <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> for more information on layouts.</p> @@ -1078,7 +1078,7 @@ setContentView(R.layout.main_screen); </p> <p>For a complete discussion on styles and themes, read -<a href="{@docRoot}guide/topics/views/themes.html">Applying Styles and Themes</a>.</p> +<a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p> <p> <strong>Source file format:</strong> XML file requiring a <code><?xml version="1.0" encoding="utf-8"?></code> declaration, and a root <code><resources></code> element containing one or more <code><style></code> tags. @@ -1132,4 +1132,4 @@ setContentView(R.layout.main_screen); </dl> <p>For examples of how to declare and apply styles and themes, read -<a href="{@docRoot}guide/topics/views/themes.html">Applying Styles and Themes</a>.</p> +<a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p> diff --git a/docs/html/guide/topics/resources/resources-i18n.jd b/docs/html/guide/topics/resources/resources-i18n.jd index 8a9bd43..b1da4cd 100644 --- a/docs/html/guide/topics/resources/resources-i18n.jd +++ b/docs/html/guide/topics/resources/resources-i18n.jd @@ -120,7 +120,7 @@ the containing file.</p> <tr> <td><code>res/layout/</code></td> <td>XML files that are compiled into screen layouts (or part of a screen). - See <a href="{@docRoot}guide/topics/views/declaring-layout.html">Declaring Layout</a></td> + See <a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a></td> </tr> <tr> <td><code>res/values/</code></td> diff --git a/docs/html/guide/topics/views/binding.jd b/docs/html/guide/topics/ui/binding.jd index ce57ac4..f9afbc5 100644 --- a/docs/html/guide/topics/views/binding.jd +++ b/docs/html/guide/topics/ui/binding.jd @@ -1,5 +1,5 @@ page.title=Binding to Data with AdapterView -parent.title=Views and Layout +parent.title=User Interface parent.link=index.html @jd:body diff --git a/docs/html/guide/topics/views/custom-components.jd b/docs/html/guide/topics/ui/custom-components.jd index 9e7943b..eccc2ca 100644 --- a/docs/html/guide/topics/views/custom-components.jd +++ b/docs/html/guide/topics/ui/custom-components.jd @@ -1,5 +1,5 @@ page.title=Building Custom Components -parent.title=Views and Layout +parent.title=User Interface parent.link=index.html @jd:body @@ -35,7 +35,7 @@ that you can use to construct your UI.</p> <p>Among the layouts available are {@link android.widget.LinearLayout LinearLayout}, {@link android.widget.FrameLayout FrameLayout}, {@link android.widget.AbsoluteLayout AbsoluteLayout}, -and others. For more examples, see <a href="layout.html">Common Layout Objects</a>.</p> +and others. For more examples, see <a href="layout-objects.html">Common Layout Objects</a>.</p> <p>If none of the prebuilt widgets or layouts meets your needs, you can create your own View subclass. If you only need to make small adjustments to an existing widget or layout, you can simply subclass diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd new file mode 100644 index 0000000..dd0b7de --- /dev/null +++ b/docs/html/guide/topics/ui/declaring-layout.jd @@ -0,0 +1,269 @@ +page.title=Declaring Layout +parent.title=User Interface +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#write">Write the XML</a></li> + <li><a href="#load">Load the XML Resource</a></li> + <li><a href="#attributes">Attributes</a> + <ol> + <li><a href="#id">ID</a></li> + <li><a href="#layout-params">Layout Parameters</a></li> + </ol> + </li> + <li><a href="#Position">Position</a></li> + <li><a href="#SizePaddingMargin">Size, Padding and Margins</a></li> + <li><a href="#example">Example Layout</a></li> + </ol> +</div> +</div> + +<p>Your layout is the architecture for the user interface in an Activity. +It defines the layout structure and holds all the elements that appear to the user. +You can declare your layout in two ways:</p> +<ul> +<li><strong>Declare UI elements in XML</strong>. Android provides a straightforward XML +vocabulary that corresponds to the View classes and subclasses, such as those for widgets and layouts.</li> +<li><strong>Instantiate layout elements at runtime</strong>. Your +application can create View and ViewGroup objects (and manipulate their properties) programmatically. </li> +</ul> + +<p>The Android framework gives you the flexibility to use either or both of these methods for declaring and managing your application's UI. For example, you could declare your application's default layouts in XML, including the screen elements that will appear in them and their properties. You could then add code in your application that would modify the state of the screen objects, including those declared in XML, at run time. </p> + +<div class="sidebox"> + <p>The <a href="{@docRoot}guide/developing/tools/adt.html">Android Development Tools</a> + (ADT) plugin for Eclipse offers a layout preview of your XML — + with the XML file opened, select the <strong>Layout</strong> tab.</p> + <p>You should also try the + <a href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Hierarchy Viewer</a> tool, + for debugging layouts — it reveals layout property values, + draws wireframes with padding/margin indicators, and full rendered views while + you debug on the emulator or device.</p> +</div> + +<p>The advantage to declaring your UI in XML is that it enables you to better separate the presentation of your application from the code that controls its behavior. Your UI descriptions are external to your application code, which means that you can modify or adapt it without having to modify your source code and recompile. For example, you can create XML layouts for different screen orientations, different device screen sizes, and different languages. Additionally, declaring the layout in XML makes it easier to visualize the structure of your UI, so it's easier to debug problems. As such, this document focuses on teaching you how to declare your layout in XML. If you're +interested in instantiating View objects at runtime, refer to the {@link android.view.ViewGroup} and +{@link android.view.View} class references.</p> + +<p>In general, the XML vocabulary for declaring UI elements closely follows the structure and naming of the classes and methods, where element names correspond to class names and attribute names correspond to methods. In fact, the correspondence is often so direct that you can guess what XML attribute corresponds to a class method, or guess what class corresponds to a given xml element. However, note that not all vocabulary is identical. In some cases, there are slight naming differences. For +example, the EditText element has a <code>text</code> attribute that corresponds to +<code>EditText.setText()</code>. </p> + +<p class="note"><strong>Tip:</strong> Learn more about different layout types in <a href="{@docRoot}guide/topics/ui/layout-objects.html">Common +Layout Objects</a>. There are also a collection of tutorials on building various layouts in the +<a href="{@docRoot}guide/tutorials/views/index.html">Hello Views</a> tutorial guide.</p> + +<h2 id="write">Write the XML</h2> + +<div class="sidebox"><p>For your convenience, the API reference documentation for UI related classes lists the available XML attributes that correspond to the class methods, including inherited attributes.</p> +<p>To learn more about the available XML elements and attributes, as well as the format of the XML file, see <a +href="{@docRoot}guide/topics/resources/available-resources.html#layoutresources">Layout Resources</a>.</p> + </div> + +<p>Using Android's XML vocabulary, you can quickly design UI layouts and the screen elements they contain, in the same way you create web pages in HTML — with a series of nested elements. </p> + +<p>Each layout file must contain exactly one root element, which must be a View or ViewGroup object. Once you've defined the root element, you can add additional layout objects or widgets as child elements to gradually build a View hierarchy that defines your layout. For example, here's an XML layout that uses a vertical {@link android.widget.LinearLayout} +to hold a {@link android.widget.TextView} and a {@link android.widget.Button}:</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Hello, I am a TextView" /> + <Button android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Hello, I am a Button" /> +</LinearLayout> +</pre> + +<p>After you've declared your layout in XML, save the file with the <code>.xml</code> extension, +in your Android project's <code>res/layout/</code> directory, so it will properly compile. </p> + +<p>We'll discuss each of the attributes shown here a little later.</p> + +<h2 id="load">Load the XML Resource</h2> + +<p>When you compile your application, each XML layout file is compiled into a +{@link android.view.View} resource. You should load the layout resource from your application code, in your +{@link android.app.Activity#onCreate(android.os.Bundle) Activity.onCreate()} callback implementation. +Do so by calling <code>{@link android.app.Activity#setContentView(int) setContentView()}</code>, +passing it the reference to your layout resource in the form of: +<code>R.layout.<em>layout_file_name</em></code> +For example, if your XML layout is saved as <code>main_layout.xml</code>, you would load it +for your Activity like so:</p> +<pre> +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView.(R.layout.main_layout); +} +</pre> + +<p>The <code>onCreate()</code> callback method in your Activity is called by the Android framework when +your Activity is launched (see the discussion on Lifecycles, in the +<a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamantals</a>, for more on this).</p> + + +<h2 id="attributes">Attributes</h2> + +<p>Every View and ViewGroup object supports their own variety of XML attributes. +Some attributes are specific to a View object (for example, TextView supports the <code>textSize</code> +attribute), but these attributes are also inherited by any View objects that may extend this class. +Some are common to all View objects, because they are inherited from the root View class (like +the <code>id</code> attribute). And, other attributes are considered "layout parameters," which are +attributes that describe certain layout orientations of the View object, as defined by that object's +parent ViewGroup object.</p> + +<h3 id="id">ID</h3> + +<p>Any View object may have an integer ID associated with it, to uniquely identify the View within the tree. +When the application is compiled, this ID is referenced as an integer, but the ID is typically +assigned in the layout XML file as a string, in the <code>id</code> attribute. +This is an XML attribute common to all View objects +(defined by the {@link android.view.View} class) and you will use it very often. +The syntax for an ID, inside an XML tag is:</p> +<pre>android:id="@+id/my_button"</pre> + +<p>The at-symbol (@) at the beginning of the string indicates that the XML parser should parse and expand the rest +of the ID string and identify it as an ID resource. The plus-symbol (+) means that this is a new resource name that must +be created and added to our resources (in the <code>R.java</code> file). There are a number of other ID resources that +are offered by the Android framework. When referencing an Android resource ID, you do not need the plus-symbol, +but must add the <code>android</code> package namespace, like so:</p> +<pre>android:id="@android:id/empty"</pre> +<p>With the <code>android</code> package namespace in place, we're now referencing an ID from the <code>android.R</code> +resources class, rather than the local resources class.</p> + +<p>In order to create views and reference them from the application, a common pattern is to:</p> +<ol> + <li>Define a view/widget in the layout file and assign it a unique ID: +<pre> +<Button android:id="@+id/my_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/my_button_text"/> +</pre> + </li> + <li>Then create an instance of the view object and capture it from the layout +(typically in the <code>{@link android.app.Activity#onCreate(Bundle) onCreate()}</code> method): +<pre> +Button myButton = (Button) findViewById(R.id.my_button); +</pre> + </li> +</ol> +<p>Defining IDs for view objects is important when creating a {@link android.widget.RelativeLayout}. +In a relative layout, sibling views can define their layout relative to another sibling view, +which is referenced by the unique ID.</p> +<p>An ID need not be unique throughout the entire tree, but it should be +unique within the part of the tree you are searching (which may often be the entire tree, so it's best +to be completely unique when possible).</p> + + +<h3 id="layout-params">Layout Parameters</h3> + +<p>XML layout attributes named <code>layout_<em>something</em></code> define +layout parameters for the View that are appropriate for the ViewGroup in which it resides.</p> + +<p>Every ViewGroup class implements a nested class that extends {@link +android.view.ViewGroup.LayoutParams}. This subclass +contains property types that define the size and position for each child view, as +appropriate for the view group. As you can see in the figure below, the parent +view group defines layout parameters for each child view (including the child view group).</p> + +<img src="{@docRoot}images/layoutparams.png" alt="" height="300" align="center"/> + +<p>Note that every LayoutParams subclass has its own syntax for setting +values. Each child element must define LayoutParams that are appropriate for its parent, +though it may also define different LayoutParams for its own children. </p> + +<p>All view groups include a width and height (<code>layout_width</code> and <code>layout_height</code>), +and each view is required to define them. +Many LayoutParams also include optional margins and +borders. You can specify width and height with exact measurements, though you probably won't want +to do this often. More often, you will tell your view to size itself either to +the dimensions required by its content, or to become as big as its parent view group +will allow (with the <var>wrap_content</var> and <var>fill_parent</var> values, respectively). +The accepted measurement types are defined in the +<a href="{@docRoot}guide/topics/resources/available-resources.html#dimension">Available Resources</a> document.</p> + + +<h2 id="Position">Layout Position</h2> + <p> + The geometry of a view is that of a rectangle. A view has a location, + expressed as a pair of <em>left</em> and <em>top</em> coordinates, and + two dimensions, expressed as a width and a height. The unit for location + and dimensions is the pixel. + </p> + + <p> + It is possible to retrieve the location of a view by invoking the methods + {@link android.view.View#getLeft()} and {@link android.view.View#getTop()}. The former returns the left, or X, + coordinate of the rectangle representing the view. The latter returns the + top, or Y, coordinate of the rectangle representing the view. These methods + both return the location of the view relative to its parent. For instance, + when getLeft() returns 20, that means the view is located 20 pixels to the + right of the left edge of its direct parent. + </p> + + <p> + In addition, several convenience methods are offered to avoid unnecessary + computations, namely {@link android.view.View#getRight()} and {@link android.view.View#getBottom()}. + These methods return the coordinates of the right and bottom edges of the + rectangle representing the view. For instance, calling {@link android.view.View#getRight()} + is similar to the following computation: <code>getLeft() + getWidth()</code>. + </p> + + +<h2 id="SizePaddingMargins">Size, Padding and Margins</h2> + <p> + The size of a view is expressed with a width and a height. A view actually + possess two pairs of width and height values. + </p> + + <p> + The first pair is known as <em>measured width</em> and + <em>measured height</em>. These dimensions define how big a view wants to be + within its parent. The + measured dimensions can be obtained by calling {@link android.view.View#getMeasuredWidth()} + and {@link android.view.View#getMeasuredHeight()}. + </p> + + <p> + The second pair is simply known as <em>width</em> and <em>height</em>, or + sometimes <em>drawing width</em> and <em>drawing height</em>. These + dimensions define the actual size of the view on screen, at drawing time and + after layout. These values may, but do not have to, be different from the + measured width and height. The width and height can be obtained by calling + {@link android.view.View#getWidth()} and {@link android.view.View#getHeight()}. + </p> + + <p> + To measure its dimensions, a view takes into account its padding. The padding + is expressed in pixels for the left, top, right and bottom parts of the view. + Padding can be used to offset the content of the view by a specific amount of + pixels. For instance, a left padding of 2 will push the view's content by + 2 pixels to the right of the left edge. Padding can be set using the + {@link android.view.View#setPadding(int, int, int, int)} method and queried by calling + {@link android.view.View#getPaddingLeft()}, {@link android.view.View#getPaddingTop()}, + {@link android.view.View#getPaddingRight()} and {@link android.view.View#getPaddingBottom()}. + </p> + + <p> + Even though a view can define a padding, it does not provide any support for + margins. However, view groups provide such a support. Refer to + {@link android.view.ViewGroup} and + {@link android.view.ViewGroup.MarginLayoutParams} for further information. + </p> + +<p>For more information about dimensions, see <a href="{@docRoot}guide/topics/resources/available-resources.html#dimension">Dimension Values</a>.</p> + + + + diff --git a/docs/html/guide/topics/ui/how-android-draws.jd b/docs/html/guide/topics/ui/how-android-draws.jd new file mode 100644 index 0000000..a511005 --- /dev/null +++ b/docs/html/guide/topics/ui/how-android-draws.jd @@ -0,0 +1,94 @@ +page.title=How Android Draws Views +parent.title=User Interface +parent.link=index.html +@jd:body + + +<p>When an Activity receives focus, it will be requested to draw its layout. +The Android framework will handle the procedure for drawing, but the Activity must provide +the root node of its layout hierarchy.</p> + +<p>Drawing begins with the root node of the layout. It is requested to measure and +draw the layout tree. Drawing is handled by walking the tree and rendering each View that + intersects the invalid region. In turn, each View group is responsible for requesting +each of its children to be drawn (with the <code>{@link android.view.View#draw(Canvas) draw()}</code> method) +and each View is responsible for drawing itself. + Because the tree is traversed in-order, + this means that parents will be drawn before (i.e., behind) their children, with + siblings drawn in the order they appear in the tree. + </p> + +<div class="sidebox"> + <p>The framework will not draw Views that are not in the invalid region, and also + will take care of drawing the Views background for you.</p> + <p>You can force a View to draw, by calling <code>{@link android.view.View#invalidate()}</code>. + </p> +</div> + +<p> + Drawing the layout is a two pass process: a measure pass and a layout pass. The measuring + pass is implemented in <code>{@link android.view.View#measure(int, int)}</code> and is a top-down traversal + of the View tree. Each View pushes dimension specifications down the tree + during the recursion. At the end of the measure pass, every View has stored + its measurements. The second pass happens in + <code>{@link android.view.View#layout(int,int,int,int)}</code> and is also top-down. During + this pass each parent is responsible for positioning all of its children + using the sizes computed in the measure pass. + </p> + + <p> + When a View's <code>measure()</code> method returns, its <code>{@link android.view.View#getMeasuredWidth()}</code> and + <code>{@link android.view.View#getMeasuredHeight()}</code> values must be set, along with those for all of + that View's descendants. A View's measured width and measured height values + must respect the constraints imposed by the View's parents. This guarantees + that at the end of the measure pass, all parents accept all of their + children's measurements. A parent View may call <code>measure()</code> more than once on + its children. For example, the parent may measure each child once with + unspecified dimensions to find out how big they want to be, then call + <code>measure()</code> on them again with actual numbers if the sum of all the children's + unconstrained sizes is too big or too small (i.e., if the children don't agree among themselves + as to how much space they each get, the parent will intervene and set the rules on the second pass). + </p> + + <div class="sidebox"><p> + To intiate a layout, call <code>{@link android.view.View#requestLayout}</code>. This method is typically + called by a View on itself when it believes that is can no longer fit within + its current bounds.</p> + </div> + + <p> + The measure pass uses two classes to communicate dimensions. The + {@link android.view.View.MeasureSpec} class is used by Views to tell their parents how they + want to be measured and positioned. The base LayoutParams class just + describes how big the View wants to be for both width and height. For each + dimension, it can specify one of:</p> + <ul> + <li> an exact number + <li><var>FILL_PARENT</var>, which means the View wants to be as big as its parent + (minus padding)</li> + <li><var>WRAP_CONTENT</var>, which means that the View wants to be just big enough to + enclose its content (plus padding).</li> + </ul> + <p>There are subclasses of LayoutParams for different subclasses of ViewGroup. + For example, AbsoluteLayout has its own subclass of LayoutParams which adds + an X and Y value. + </p> + + <p> + MeasureSpecs are used to push requirements down the tree from parent to + child. A MeasureSpec can be in one of three modes:</p> + <ul> + <li><var>UNSPECIFIED</var>: This is used by a parent to determine the desired dimension + of a child View. For example, a LinearLayout may call <code>measure()</code> on its child + with the height set to <var>UNSPECIFIED</var> and a width of <var>EXACTLY</var> 240 to find out how + tall the child View wants to be given a width of 240 pixels.</li> + <li><var>EXACTLY</var>: This is used by the parent to impose an exact size on the + child. The child must use this size, and guarantee that all of its + descendants will fit within this size.</li> + <li><var>AT_MOST</var>: This is used by the parent to impose a maximum size on the + child. The child must gurantee that it and all of its descendants will fit + within this size.</li> + </ul> + + + diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd new file mode 100644 index 0000000..ccc8ff6 --- /dev/null +++ b/docs/html/guide/topics/ui/index.jd @@ -0,0 +1,235 @@ +page.title=User Interface +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + + <h2>Key classes and packages</h2> + <ol> + <li>{@link android.view.View}</li> + <li>{@link android.view.ViewGroup}</li> + <li>{@link android.widget}</li> + </ol> + + <h2>In this document</h2> + <ol> + <li><a href="#ViewHierarchy">View Hierarchy</a></li> + <li><a href="#Layout">Layout</a></li> + <li><a href="#Widgets">Widgets</a></li> + <li><a href="#Events">UI Events</a></li> + <li><a href="#Menus">Menus</a></li> + <li><a href="#Advanced">Advanced Topics</a> + <ol> + <li><a href="#Adapters">Adapters</a></li> + <li><a href="#StylesAndThemes">Styles and Themes</a></li> + </ol> + </li> + </ol> +</div> +</div> + +<p>In an Android application, the user interface is built using {@link android.view.View} and +{@link android.view.ViewGroup} objects. There are many types of views and view groups, each of which +is a descendant of the {@link android.view.View} class.</p> + +<p>View objects are the basic units of user interface expression on the Android platform. +The View class serves as the base for subclasses called "widgets," which offer fully implemented +UI objects, like text fields and buttons. The ViewGroup class serves as the base for subclasses called "layouts," +which offer different kinds of layout architecture, like linear, tabular and relative.</p> + +<p>A View object is a data structure whose properties store the layout parameters and content for a specific +rectangular area of the screen. A View object handles its own measurement, layout, drawing, focus change, +scrolling, and key/gesture interactions for the rectangular area of the screen in which it resides. As an +object in the user interface, a View is also a point of interaction for the user and the receiver +of the interaction events.</p> + + +<h2 id="ViewHierarchy">View Hierarchy</h2> + +<p>On the Android platform, you define an Activity's UI using a hierarchy of View and ViewGroup nodes, +as shown in the diagram below. This hierarchy tree can be as simple or complex as you need it to be, and you +can build it up using Android's set of predefined widgets and layouts, or with custom Views that you +create yourself.</p> + +<img src="{@docRoot}images/viewgroup.png" alt="" width="312" height="211" align="center"/> + +<p> +In order to attach the view hierarchy tree to the screen for rendering, your Activity must call the +<code>{@link android.app.Activity#setContentView(int) setContentView()}</code> +method and pass a reference to the root node object. The Android system +receives this reference and uses it to invalidate, measure, and draw the tree. The root node of the hierarchy requests +that its child nodes draw themselves — in turn, each view group node is responsible for calling +upon each of its own child views to draw themselves. +The children may request a size and location within the parent, but the parent object has the final +decision on where how big each child can be. Android parses +the elements of your layout in-order (from the top of the hierarchy tree), instantiating the Views and +adding them to their parent(s). Because these are drawn in-order, if there are elements that +overlap positions, the last one to be drawn will lie on top of others previously drawn to that space.</p> + +<p>For a more detailed discussion on how view hierarchies are measured +and drawn, read <a href="how-android-draws.html">How Android Draws Views</a>.</p> + + +<h2 id="Layout">Layout</h2> + +<p>The most common way to define your layout and express the view hierarchy is with an XML layout file. +XML offers a human-readable structure for the layout, much like HTML. Each element in XML is +either a View or ViewGroup object (or descendent thereof). View objects are leaves in the tree, +ViewGroup objects are branches in the tree (see the View Hierarchy figure above).</p> +<p>The name of an XML element +is respective to the Java class that it represents. So a <code><TextView></code> element creates +a {@link android.widget.TextView} in your UI, and a <code><LinearLayout></code> element creates +a {@link android.widget.LinearLayout} view group. When you load a layout resource, +the Android system initializes these run-time objects, corresponding to the elements in your layout.</p> + +<p>For example, a simple vertical layout with a text view and a button looks like this:</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Hello, I am a TextView" /> + <Button android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Hello, I am a Button" /> +</LinearLayout> +</pre> + +<p>Notice that the LinearLayout element contains both the TextView and the Button. You can nest +another LinearLayout (or other type of view group) inside here, to lengthen the view hierarchy and create a more +complex layout.</p> + +<p>For more on building a UI layout, read <a href="declaring-layout.html">Declaring Layout</a>. + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <p><b>Tip:</b> You can also draw View and ViewGroups objects in Java code, + using the <code>{@link android.view.ViewGroup#addView(View)}</code> methods + to dynamically insert new View and ViewGroup objects.</p> +</div> +</div> + +<p>There are a variety of ways in which you can layout your views. Using more and different kinds of view groups, +you can structure child views and view groups in an infinite number of ways. +Some pre-defined view groups offered by Android (called layouts) include LinearLayout, RelativeLayout, AbsoluteLayout, +TableLayout, GridLayout and others. Each offers a unique set of layout parameters that are used to define the +positions of child views and layout structure.</p> +<p>To learn about some of the different kinds of view groups used for a layout, +read <a href="layout-objects.html">Common Layout Objects</a>.</p> + + +<h2 id="Widgets">Widgets</h2> + +<p>A widget is a View object that serves as an interface for interaction with the user. +Android provides a set of fully implemented +widgets, like buttons, checkboxes, and text-entry fields, so you can quickly build your UI. +Some widgets provided by Android are more complex, like a date picker, a clock, and zoom controls. +But you're not limited to the kinds of widgets provided by the Android platform. If you'd +like to do something more customized and create your own actionable elements, you can, by defining your own +View object or by extending and combining existing widgets.</p> +<p>Read more in <a href="custom-components.html">Building Custom Components</a>.</p> + +<p>For a list of the widgets provided by Android, see the {@link android.widget} package.</p> + + +<h2 id="Events">UI Events</h2> + +<p>Once you've added some Views/widgets to the UI, you probably want to know about the +user's interaction with them, so you can perform actions. To be informed of UI events, you need to +do one of two things:</p> +<ul> + <li><strong>Define an event listener and register it with the View.</strong> More often than not, +this is how you'll listen for events. The View class contains a collection of nested interfaces named +On<em><something></em>Listener, each with a callback method called <code>On<em><something></em>()</code>. +For example, {@link android.view.View.OnClickListener} (for handling "clicks" on a View), +{@link android.view.View.OnTouchListener} (for handling touch screen events in a View), and +{@link android.view.View.OnKeyListener} (for handling device key presses within a View). So if you want your View +to be notified when it is "clicked" (such as when a button is selected), implement OnClickListener and define +its <code>onClick()</code> callback method (where you perform the action upon click), and register it +to the View with <code>{@link android.view.View#setOnClickListener(View.OnClickListener) setOnClickListener()}</code>. +</li> + <li><strong>Override an existing callback method for the View.</strong> This is +what you should do when you've implemented your own View class and want to listen for specific events +that occur within it. Example events you can handle include when the +screen is touched (<code>{@link android.view.View#onTouchEvent(MotionEvent) onTouchEvent()}</code>), when +the trackball is moved (<code>{@link android.view.View#onTrackballEvent(MotionEvent) onTrackballEvent()}</code>), +or when a key on the device is pressed (<code>{@link android.view.View#onKeyDown(int, KeyEvent) +onKeyDown()}</code>). This allows you to define the default behavior for each event inside your custom View and determine +whether the event should be passed on to some other child View. Again, these are callbacks to the View class, +so your only chance to define them is when you +<a href="{@docRoot}guide/topics/ui/custom-components.html">build a custom component</a>. +</li> +</ul> + +<p>Continue reading about handling user interaction with Views in the <a href="ui-events.html">Handling UI Events</a> +document.</p> + + +<h2 id="Menus">Menus</h2> + +<p>Application menus are another important part of an application's UI. Menus offers a reliable interface that reveals +application functions and settings. The most common application menu is revealed by pressing +the MENU key on the device. However, you can also add Context Menus, which may be revealed when the user presses +and holds down on an item.</p> + +<p>Menus are also structured using a View hierarchy, but you don't define this structure yourself. Instead, +you define the <code>{@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}</code> or +<code>{@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenu.ContextMenuInfo) onCreateContextMenu()}</code> +callback methods for your Activity and declare the items that you want to include in your menu. +At the appropriate time, Android will automatically create the necessary View hierarchy for the menu and +draw each of your menu items in it.</p> + +<p>Menus also handle their own events, so there's no need to register event listeners on the items in your menu. +When an item in your menu is selected, the <code>{@link android.app.Activity#onOptionsItemSelected(MenuItem) +onOptionsItemSelected()}</code> or +<code>{@link android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}</code> +method will be called by the framework.</p> + +<p>And just like your application layout, you have the option to declare the items for you menu in an XML file.</p> + +<p>Read <a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a> to learn more.</p> + + +<h2 id="Advanced">Advanced Topics</h2> + +<p>Once you've grappled the fundamentals of creating a user interface, you can explore +some advanced features for creating a more complex application interface.</p> + +<h3 id="Adapters">Adapters</h3> + +<p>Sometimes you'll want to populate a view group with some information that can't be hard-coded, instead, +you want to bind your view to an external source of data. To do this, you use an AdapterView as +your view group and each child View is initialized and populated with data from the Adapter.</p> +<p>The AdapterView object is an implementation of ViewGroup that determines its child views +based on a given Adapter object. The Adapter acts like a courier between your data source (perhaps an +array of external strings) and the AdapterView, which displays it. There are several implementations +of the Adapter class, for specific tasks, such as the CursorAdapter for reading database data from a Cursor, +or an ArrayAdapter for reading from an arbitrary array.</p> +<p>To learn more about using an Adapter to populate your views, read +<a href="binding.html">Binding to Data with AdapterView</a>.</p> + + +<h3 id="StylesAndThemes">Styles and Themes</h3> + +<p>Perhaps you're not satisfied with the look of the standard widgets. To revise them, you can create some +of your own styles and themes.</p> + +<ul> + <li>A style is a set of one or more formatting attributes that you can apply as a unit to individual elements +in your layout. For example, you could define a style that specifies a certain text size and color, then +apply it to only specific View elements.</li> + <li>A theme is a set of one or more formatting attributes that you can apply as a unit to all activities in +an application, or just a single activity. For example, you could define a theme that sets specific colors for +the window frame and the panel background, and sets text sizes and colors for menus. This theme can then be +applied to specific activities or the entire application.</li> +</ul> + +<p>Styles and themes are resources. Android provides some default style and theme resources that you can use, +or you can declare your own custom style and theme resources.</p> +<p>Learn more about using styles and themes in the +<a href="themes.html">Applying Styles and Themes</a> document.</p> diff --git a/docs/html/guide/topics/views/layout.jd b/docs/html/guide/topics/ui/layout-objects.jd index a6fec35..cf85fd6 100644 --- a/docs/html/guide/topics/views/layout.jd +++ b/docs/html/guide/topics/ui/layout-objects.jd @@ -1,5 +1,5 @@ page.title=Common Layout Objects -parent.title=Views and Layout +parent.title=User Interface parent.link=index.html @jd:body @@ -20,6 +20,8 @@ parent.link=index.html <p>This section describes some of the more common types of layout objects to use in your applications. Like all layouts, they are subclasses of {@link android.view.ViewGroup ViewGroup}.</p> +<p>Also see the <a href="{@docRoot}guide/tutorials/views/index.html">Hello Views</a> tutorials for +some guidance on using more Android View layouts.</p> <h2 id="framelayout">FrameLayout</h2> <p>{@link android.widget.FrameLayout FrameLayout} is the simplest type of layout @@ -95,9 +97,42 @@ cells empty, but cells cannot span columns, as they can in HTML.</p> Each row has zero or more cells, each of which is defined by any kind of other View. So, the cells of a row may be composed of a variety of View objects, like ImageView or TextView objects. A cell may also be a ViewGroup object (for example, you can nest another TableLayout as a cell).</p> -<p>The following image shows a table layout, with the invisible cell borders displayed as dotted lines. </p> +<p>The following sample layout has two rows and two cells in each. The accompanying screenshot shows the +result, with cell borders displayed as dotted lines (added for visual effect). </p> -<img src="{@docRoot}images/table_layout.png" alt="" /> +<table class="columns"> + <tr> + <td> + <pre> +<?xml version="1.0" encoding="utf-8"?> +<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:stretchColumns="1"> + <TableRow> + <TextView + android:text="@string/table_layout_4_open" + android:padding="3dip" /> + <TextView + android:text="@string/table_layout_4_open_shortcut" + android:gravity="right" + android:padding="3dip" /> + </TableRow> + + <TableRow> + <TextView + android:text="@string/table_layout_4_save" + android:padding="3dip" /> + <TextView + android:text="@string/table_layout_4_save_shortcut" + android:gravity="right" + android:padding="3dip" /> + </TableRow> +</TableLayout> +</pre></td> + <td><img src="{@docRoot}images/table_layout.png" alt="" style="margin:0" /></td> + </tr> +</table> <p>Columns can be hidden, marked to stretch and fill the available screen space, or can be marked as shrinkable to force the column to shrink until the table @@ -127,13 +162,54 @@ TableLayout</a> tutorial.</p> will be aligned relative to screen center. Also, because of this ordering, if using XML to specify this layout, the element that you will reference (in order to position other view objects) must be listed in the XML file before you refer to it from the other views via its reference ID. </p> -<p>Here is an example relative layout with the visible and invisible elements outlined. - The root screen layout object is a RelativeLayout object. </p> +<p>The example below shows an XML file and the resulting screen in the UI. +Note that the attributes that refer to relative elements (e.g., <var>layout_toLeft</var>) +refer to the ID using the syntax of a relative resource +(<var>@id/<em>id</em></var>). </p> + +<table class="columns"> + <tr> + <td> + <pre> +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:background="@drawable/blue" + android:padding="10px" > + + <TextView android:id="@+id/label" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Type here:" /> + + <EditText android:id="@+id/entry" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:background="@android:drawable/editbox_background" + android:layout_below="@id/label" /> + + <Button android:id="@+id/ok" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@id/entry" + android:layout_alignParentRight="true" + android:layout_marginLeft="10px" + android:text="OK" /> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toLeftOf="@id/ok" + android:layout_alignTop="@id/ok" + android:text="Cancel" /> +</RelativeLayout> +</pre></td> + <td><img src="{@docRoot}images/designing_ui_layout_example.png" alt="" style="margin:0" /></td> + </tr> +</table> -<img src="{@docRoot}images/designing_ui_relative_layout.png" alt="" /> -<p>This diagram shows the class names of the screen elements, followed by a list - of the properties of each. Some of these properties are supported directly by +<p>Some of these properties are supported directly by the element, and some are supported by its LayoutParams member (subclass RelativeLayout for all the elements in this screen, because all elements are children of a RelativeLayout parent object). The defined RelativeLayout parameters are: <code>width</code>, <code>height</code>, diff --git a/docs/html/guide/topics/views/menus.jd b/docs/html/guide/topics/ui/menus.jd index 489cd07..ed796ee 100644 --- a/docs/html/guide/topics/views/menus.jd +++ b/docs/html/guide/topics/ui/menus.jd @@ -9,7 +9,7 @@ parent.link=index.html <ol> <li><a href="#options-menu">Options Menu</a></li> <li><a href="#context-menu">Context Menu</a></li> - <li><a href="#sub-menu">Sub Menu</a></li> + <li><a href="#submenu">Submenu</a></li> <li><a href="#xml">Define Menus in XML</a></li> <li><a href="#features">Menu Features</a> <ol> @@ -20,6 +20,12 @@ parent.link=index.html </ol> </li> </ol> + <h2>Key classes</h2> + <ol> + <li>{@link android.view.Menu}</li> + <li>{@link android.view.ContextMenu}</li> + <li>{@link android.view.SubMenu}</li> + </ol> </div> </div> @@ -47,9 +53,9 @@ for developers to provide standardized application menus for various situations. <dt><strong>Context Menu</strong></dt> <dd>This is a floating list of menu items that may appear when you perform a long-press on a View (such as a list item). </dd> - <dt><strong>Sub Menu</strong></dt> + <dt><strong>Submenu</strong></dt> <dd>This is a floating list of menu items that is revealed by an item in the Options Menu - or a Context Menu. A Sub Menu item cannot support nested Sub Menus. </dd> + or a Context Menu. A Submenu item cannot support nested Submenus. </dd> </dl> @@ -63,7 +69,7 @@ is automatically added when there are more than six items.</p> <p>The Options Menu is where you should include basic application functions and any necessary navigation items (e.g., to a home screen or application settings). -You can also add <a href="#sub-menu">Sub Menus</a> for organizing topics +You can also add <a href="#submenu">Submenus</a> for organizing topics and including extra menu functionality.</p> <p>When this menu is opened for the first time, @@ -127,7 +133,7 @@ and we recommend you do it that way for easier localization).</p> <p class="note"><strong>Tip:</strong> If you have several menu items that can be grouped together with a title, -consider organizing them into a <a href="#sub-menu">Sub Menu</a>.</p> +consider organizing them into a <a href="#submenu">Submenu</a>.</p> <h3>Adding icons</h3> <p>Icons can also be added to items that appears in the Icon Menu with @@ -136,8 +142,8 @@ consider organizing them into a <a href="#sub-menu">Sub Menu</a>.</p> menu.add(0, MENU_QUIT, 0, "Quit") .setIcon(R.drawable.menu_quit_icon);</pre> -<h3>Modifying the options menu</h3> -<p>If you want to sometimes re-write the options menu as it is opened, override the +<h3>Modifying the menu</h3> +<p>If you want to sometimes re-write the Options Menu as it is opened, override the <code>{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}</code> method, which is called each time the menu is opened. This will pass you the Menu object, just like the <code>onCreateOptionsMenu()</code> callback. This is useful if you'd like to add or remove @@ -225,7 +231,7 @@ in the list is registered to this context menu.</p> -<h2 id="sub-menu">Sub Menus</h2> +<h2 id="submenu">Submenus</h2> <p>A sub menu can be added within any menu, except another sub menu. These are very useful when your application has a lot of functions that may be organized in topics, like the items in a PC application's menu bar (File, Edit, View, etc.).</p> @@ -254,7 +260,7 @@ public boolean onCreateOptionsMenu(Menu menu) { <p>Callbacks for items selected in a sub menu are made to the parent menu's callback method. For the example above, selections in the sub menu will be handled by the <code>onOptionsItemSelected()</code> callback.</p> -<p>You can also add Sub Menus when you <a href="#xml">define the parent menu in XML</a>.</p> +<p>You can also add Submenus when you <a href="#xml">define the parent menu in XML</a>.</p> <h2 id="xml">Define Menus in XML</h2> @@ -269,7 +275,7 @@ This is where you should keep all XML files that define your application menus.< three valid elements: <code><menu></code>, <code><group></code> and <code><item></code>. The <code>item</code> and <code>group</code> elements must be children of a <code>menu</code>, but <code>item</code> elements may also be the children of a <code>group</code>, and another <code>menu</code> element may be the child -of an <code>item</code> (to create a Sub Menu). Of course, the root node of any file +of an <code>item</code> (to create a Submenu). Of course, the root node of any file must be a <code>menu</code> element.</p> <p>As an example, we'll define the same menu created in the <a href="#options-menu">Options Menu</a> section, @@ -302,7 +308,7 @@ passing it a pointer to our menu resource and the Menu object given by the callb and it keeps your application code clean.</p> <p>You can define <a href="#groups">menu groups</a> by wrapping <code>item</code> elements in a <code>group</code> -element, and create Sub Menus by nesting another <code>menu</code> inside an <code>item</code>. +element, and create Submenus by nesting another <code>menu</code> inside an <code>item</code>. Each element also supports all the necessary attributes to control features like shortcut keys, checkboxes, icons, and more. To learn about these attributes and more about the XML syntax, see the Menus topic in the <a href="{@docRoot}guide/topics/resources/available-resources.html#menus">Available @@ -367,7 +373,7 @@ assign the same group ID to each menu item and call <code>{@link android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}</code>. In this case, you don't need to call <code>setCheckable()</code> on each menu items, because the group as a whole is set checkable. Here's an example of -two mutually exclusive options in a sub-menu:</p> +two mutually exclusive options in a Submenu:</p> <pre> SubMenu subMenu = menu.addSubMenu("Color"); subMenu.add(COLOR_MENU_GROUP, COLOR_RED_ID, 0, "Red"); diff --git a/docs/html/guide/topics/views/themes.jd b/docs/html/guide/topics/ui/themes.jd index a206a4b..d684512 100644 --- a/docs/html/guide/topics/views/themes.jd +++ b/docs/html/guide/topics/ui/themes.jd @@ -1,5 +1,5 @@ page.title=Applying Styles and Themes -parent.title=Views and Layout +parent.title=User Interface parent.link=index.html @jd:body diff --git a/docs/html/guide/topics/ui/ui-events.jd b/docs/html/guide/topics/ui/ui-events.jd new file mode 100644 index 0000000..f4d114a --- /dev/null +++ b/docs/html/guide/topics/ui/ui-events.jd @@ -0,0 +1,283 @@ +page.title=Handling UI Events +parent.title=User Interface +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#EventListeners">Event Listeners</a></li> + <li><a href="#EventHandlers">Event Handlers</a></li> + <li><a href="#TouchMode">Touch Mode</a></li> + <li><a href="#HandlingFocus">Handling Focus</a></li> + </ol> + + <h2>See also</h2> + <ol> + <li><a href="{@docRoot}guide/tutorials/views/hello-formstuff.html">Hello Form Stuff tutorial</a></li> + </ol> +</div> +</div> + +<p>On Android, there's more than one way to intercept the events from a user's interaction with your application. +When considering events within your user interface, the approach is to capture the events from +the specific View object that the user interacts with. The View class provides the means to do so.</p> + +<p>Within the various View classes that you'll use to compose your layout, you may notice several public callback +methods that look useful for UI events. These methods are called by the Android framework when the +respective action occurs on that object. For instance, when a View (such as a Button) is touched, +the <code>onTouchEvent()</code> method is called on that object. However, in order to intercept this, you must extend +the class and override the method. Obviously, extending every View object +you want to use (just to handle an event) would be obsurd. This is why the View class also contains +a collection of nested interfaces with callbacks that you can much more easily define. These interfaces, +called <a href="#EventListeners">event listeners</a>, are your ticket to capturing the user interaction with your UI.</p> + +<p>While you will more commonly use the event listeners to listen for user interaction, there may +come a time when you do want to extend a View class, in order to build a custom component. +Perhaps you want to extend the {@link android.widget.Button} +class to make something more fancy. In this case, you'll be able to define the default event behaviors for your +class using the class <a href="#EventHandlers">event handlers</a>.</p> + + +<h2 id="EventListeners">Event Listeners</h2> + +<p>An event listener is an interface in the {@link android.view.View} class that contains a single +callback method. These methods will be called by the Android framework when the View to which the listener has +been registered is triggered by user interaction with the item in the UI.</p> + +<p>Included in the event listener interfaces are the following callback methods:</p> + +<dl> + <dt><code>onClick()</code></dt> + <dd>From {@link android.view.View.OnClickListener}. + This is called when the user either touches the item + (when in touch mode), or focuses upon the item with the navigation-keys or trackball and + presses the suitable "enter" key or presses down on the trackball.</dd> + <dt><code>onLongClick()</code></dt> + <dd>From {@link android.view.View.OnLongClickListener}. + This is called when the user either touches and holds the item (when in touch mode), or + focuses upon the item with the navigation-keys or trackball and + presses and holds the suitable "enter" key or presses and holds down on the trackball (for one second).</dd> + <dt><code>onFocusChange()</code></dt> + <dd>From {@link android.view.View.OnFocusChangeListener}. + This is called when the user navigates onto or away from the item, using the navigation-keys or trackball.</dd> + <dt><code>onKey()</code></dt> + <dd>From {@link android.view.View.OnKeyListener}. + This is called when the user is focused on the item and presses or releases a key on the device.</dd> + <dt><code>onTouch()</code></dt> + <dd>From {@link android.view.View.OnTouchListener}. + This is called when the user performs an action qualified as a touch event, including a press, a release, + or any movement gesture on the screen (within the bounds of the item).</dd> + <dt><code>onCreateContextMenu()</code></dt> + <dd>From {@link android.view.View.OnCreateContextMenuListener}. + This is called when a Context Menu is being built (as the result of a sustained "long click"). See the discussion + on context menus in <a href="{@docRoot}guide/topics/ui/menus.html#context-menu">Creating Menus</a> for more information.</dd> +</dl> + +<p>These methods are the sole inhabitants of their respective interface. To define one of these methods +and handle your events, implement the nested interface in your Activity or define it as an anonymous class. +Then, pass an instance of your implementation +to the respective <code>View.set...Listener()</code> method. (E.g., call +<code>{@link android.view.View#setOnClickListener(View.OnClickListener) setOnClickListener()}</code> +and pass it your implementation of the {@link android.view.View.OnClickListener OnClickListener}.)</p> + +<p>The example below shows how to register an on-click listener for a Button. </p> + +<pre> +// Create an anonymous implementation of OnClickListener +private OnClickListener mCorkyListener = new OnClickListener() { + public void onClick(View v) { + // do something when the button is clicked + } +}; + +protected void onCreate(Bundle savedValues) { + ... + // Capture our button from layout + Button button = (Button)findViewById(R.id.corky); + // Register the onClick listener with the implementation above + button.setOnClickListener(mCorkyListener); + ... +} +</pre> + +<p>You may also find it more conventient to implement OnClickListener as a part of your Activity. +This will avoid the extra class load and object allocation. For example:</p> +<pre> +public class ExampleActivity extends Activity implements OnClickListener { + protected void onCreate(Bundle savedValues) { + ... + Button button = (Button)findViewById(R.id.corky); + button.setOnClickListener(this); + } + + // Implement the OnClickListener callback + public void onClick(View v) { + // do something when the button is clicked + } + ... +} +</pre> + +<p>Notice that the <code>onClick()</code> callback in the above example has +no return value, but some other event listener methods must return a boolean. The reason +depends on the event. For the few that do, here's why:</p> +<ul> + <li><code>{@link android.view.View.OnLongClickListener#onLongClick(View) onLongClick()}</code> - + This returns a boolean to indicate whether you have consumed the event and it should not be carried further. + That is, return <em>true</em> to indicate that you have handled the event and it should stop here; + return <em>false</em> if you have not handled it and/or the event should continue to any other + on-click listeners.</li> + <li><code>{@link android.view.View.OnKeyListener#onKey(View,int,KeyEvent) onKey()}</code> - + This returns a boolean to indicate whether you have consumed the event and it should not be carried further. + That is, return <em>true</em> to indicate that you have handled the event and it should stop here; + return <em>false</em> if you have not handled it and/or the event should continue to any other + on-key listeners.</li> + <li><code>{@link android.view.View.OnTouchListener#onTouch(View,MotionEvent) onTouch()}</code> - + This returns a boolean to indicate whether your listener consumes this event. The important thing is that + this event can have multiple actions that follow each other. So, if you return <em>false</em> when the + down action event is received, you indicate that you have not consumed the event and are also + not interested in subsequent actions from this event. Thus, you will not be called for any other actions + within the event, such as a fingure gesture, or the eventual up action event.</li> +</ul> + +<p>Remember that key events are always delivered to the View currently in focus. They are dispatched starting from the top +of the View hierarchy, and then down, until they reach the appropriate destination. If your View (or a child of your View) +currently has focus, then you can see the event travel through the <code>{@link android.view.View#dispatchKeyEvent(KeyEvent) +dispatchKeyEvent()}</code> method. As an alternative to capturing key events through your View, you can also receive +all of the events inside your Activity with <code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code> +and <code>{@link android.app.Activity#onKeyUp(int,KeyEvent) onKeyUp()}</code>.</p> + +<p class="note"><strong>Note:</strong> Android will call event handlers first and then the appropriate default +handlers from the class definition second. As such, returning <em>true</em> from these event listeners will stop +the propagation of the event to other event listeners and will also block the callback to the +default event handler in the View. So be certain that you want to terminate the event when you return <em>true</em>.</p> + + +<h2 id="EventHandlers">Event Handlers</h2> + +<p>If you're building a custom component from View, then you'll be able to define several callback methods +used as default event handlers. +In the document on <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>, +you'll learn see some of the common callbacks used for event handling, including:</p> +<ul> + <li><code>{@link android.view.View#onKeyDown}</code> - Called when a new key event occurs.</li> + <li><code>{@link android.view.View#onKeyUp}</code> - Called when a key up event occurs.</li> + <li><code>{@link android.view.View#onTrackballEvent}</code> - Called when a trackball motion event occurs.</li> + <li><code>{@link android.view.View#onTouchEvent}</code> - Called when a touch screen motion event occurs.</li> + <li><code>{@link android.view.View#onFocusChanged}</code> - Called when the view gains or loses focus.</li> +</ul> +<p>There are some other methods that you should be awere of, which are not part of the View class, +but can directly impact the way you're able to handle events. So, when managing more complex events inside +a layout, consider these other methods:</p> +<ul> + <li><code>{@link android.app.Activity#dispatchTouchEvent(MotionEvent) + Activity.dispatchTouchEvent(MotionEvent)}</code> - This allows your {@link + android.app.Activity} to intercept all touch events before they are dispatched to the window.</li> + <li><code>{@link android.view.ViewGroup#onInterceptTouchEvent(MotionEvent) + ViewGroup.onInterceptTouchEvent(MotionEvent)}</code> - This allows a {@link + android.view.ViewGroup} to watch events as they are dispatched to child Views.</li> + <li><code>{@link android.view.ViewParent#requestDisallowInterceptTouchEvent(boolean) + ViewParent.requestDisallowInterceptTouchEvent(boolean)}</code> - Call this + upon a parent View to indicate that it should not intercept touch events with <code>{@link + android.view.ViewGroup#onInterceptTouchEvent(MotionEvent)}</code>.</li> +</ul> + +<h2 id="TouchMode">Touch Mode</h2> +<p> +When a user is navigating a user interface with directional keys or a trackball, it is +necessary to give focus to actionable items (like buttons) so the user can see +what will accept input. If the device has touch capabilities, however, and the user +begins interacting with the interface by touching it, then it is no longer necessary to +highlight items, or give focus to a particular View. Thus, there is a mode +for interaction named "touch mode." +</p> +<p> +For a touch-capable device, once the user touches the screen, the device +will enter touch mode. From this point onward, only Views for which +{@link android.view.View#isFocusableInTouchMode} is true will be focusable, such as text editing widgets. +Other Views that are touchable, like buttons, will not take focus when touched; they will +simply fire their on-click listeners when pressed. +</p> +<p> +Any time a user hits a directional key or scrolls with a trackball, the device will +exit touch mode, and find a view to take focus. Now, the user may resume interacting +with the user interface without touching the screen. +</p> +<p> +The touch mode state is maintained throughout the entire system (all windows and activities). +To query the current state, you can call +{@link android.view.View#isInTouchMode} to see whether the device is currently in touch mode. +</p> + + +<h2 id="HandlingFocus">Handling Focus</h2> + +<p>The framework will handle routine focus movement in response to user input. +This includes changing the focus as Views are removed or hidden, or as new +Views become available. Views indicate their willingness to take focus +through the <code>{@link android.view.View#isFocusable()}</code> method. To change whether a View can take +focus, call <code>{@link android.view.View#setFocusable(boolean) setFocusable()}</code>. When in touch mode, +you may query whether a View allows focus with <code>{@link android.view.View#isFocusableInTouchMode()}</code>. +You can change this with <code>{@link android.view.View#setFocusableInTouchMode(boolean) setFocusableInTouchMode()}</code>. +</p> + +<p>Focus movement is based on an algorithm which finds the nearest neighbor in a +given direction. In rare cases, the default algorithm may not match the +intended behavior of the developer. In these situations, you can provide +explicit overrides with the following XML attributes in the layout file: +<var>nextFocusDown</var>, <var>nextFocusLeft</var>, <var>nextFocusRight</var>, and +<var>nextFocusUp</var>. Add one of these attributes to the View <em>from</em> which +the focus is leaving. Define the value of the attribute to be the id of the View +<em>to</em> which focus should be given. For example:</p> +<pre> +<LinearLayout + android:orientation="vertical" + ... > + <Button android:id="@+id/top" + android:nextFocusUp="@+id/bottom" + ... /> + <Button android:id="@+id/bottom" + android:nextFocusDown="@+id/top" + ... /> +</LinearLayout> +</pre> + +<p>Ordinarily, in this vertical layout, navigating up from the first Button would not go +anywhere, nor would navigating down from the second Button. Now that the top Button has +defined the bottom one as the <var>nextFocusUp</var> (and vice versa), the navigation focus will +cycle from top-to-bottom and bottom-to-top.</p> + +<p>If you'd like to declare a View as focusable in your UI (when it is traditionally not), +add the <code>android:focusable</code> XML attribute to the View, in your layout declaration. +Set the value <var>true</var>. You can also declare a View +as focusable while in Touch Mode with <code>android:focusableInTouchMode</code>.</p> +<p>To request a particular View to take focus, call <code>{@link android.view.View#requestFocus()}</code>.</p> +<p>To listen for focus events (be notified when a View receives or looses focus), use +<code>{@link android.view.View.OnFocusChangeListener#onFocusChange(View,boolean) onFocusChange()}</code>, +as discussed in the <a href="#EventListeners">Event Listeners</a> section, above.</p> + + + +<!-- +<h2 is="EventCycle">Event Cycle</h2> + <p>The basic cycle of a View is as follows:</p> + <ol> + <li>An event comes in and is dispatched to the appropriate View. The View + handles the event and notifies any listeners.</li> + <li>If, in the course of processing the event, the View's bounds may need + to be changed, the View will call {@link android.view.View#requestLayout()}.</li> + <li>Similarly, if in the course of processing the event the View's appearance + may need to be changed, the View will call {@link android.view.View#invalidate()}.</li> + <li>If either {@link android.view.View#requestLayout()} or {@link android.view.View#invalidate()} were called, + the framework will take care of measuring, laying out, and drawing the tree + as appropriate.</li> + </ol> + + <p class="note"><strong>Note:</strong> The entire View tree is single threaded. You must always be on + the UI thread when calling any method on any View. + If you are doing work on other threads and want to update the state of a View + from that thread, you should use a {@link android.os.Handler}. + </p> +--> diff --git a/docs/html/guide/topics/views/declaring-layout.jd b/docs/html/guide/topics/views/declaring-layout.jd deleted file mode 100644 index 43afdf7..0000000 --- a/docs/html/guide/topics/views/declaring-layout.jd +++ /dev/null @@ -1,228 +0,0 @@ -page.title=Declaring Layout -parent.title=Views and Layout -parent.link=index.html -@jd:body - -<div id="qv-wrapper"> -<div id="qv"> - <h2>In this document</h2> - <ol> - <li><a href="#LoadingTheResource">Loading the XML Resource</a></li> - <li><a href="#Position">Position</a></li> - <li><a href="#SizePaddingMargin">Size, Padding and Margins</a></li> - </ol> -</div> -</div> - -<p>You can create your application's user interface in two ways: -<ul> -<li><strong>Declare UI elements statically, in XML</strong>. Android provides a straightforward XML -vocabulary that corresponds to the View classes and subclasses, such as those for widgets and layouts. </li> -<li><strong>Instantiate screen elements at runtime</strong>. Your -application can refer to or create View or other class objects and manipulate their properties programmatically. </li> -</ul> - -<p>One advantage of declaring your UI in XML is that it enables you to better separate the presentation of your application from the code that controls it's behavior. Your UI description is external to your application code, which means that you can modify or adapt it without having to modify your source code and recompile. For example, you can create XML layouts for different screen orientations and for a variety of device screen sizes or languages. Additionally, declaring in XML makes it easier to see the elements and structure of your UI, so it's easier to debug problems. </p> - -<div class="sidebox"> - <p>The <a href="{@docRoot}guide/developing/tools/adt.html">Android Development Tools</a> - (ADT) plugin for Eclipse offers a layout preview of your XML — - with the XML file opened, select the <strong>Layout</strong> tab.</p> - <p>You should also try the - <a href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Hierarchy Viewer</a> tool, - for debugging layouts — it reveals layout property values, - draws wireframes with padding/margin indicators, and full rendered views while - you debug on the emulator or device.</p> -</div> - -<p>The Android framework gives you the flexibility to use either or both of these ways of declaring and managing your application's UI. For example, you could declare your application's default layouts in XML, including the screen elements that will appear in them and their properties. You could then add code in your application that would modify the state of the screen objects, including those declared in XML, at run time. </p> - -<p>You build your application's UI in approximately the same way, whether you are declaring it in XML or programmatically. In both cases, your UI will be a tree structure that may include multiple View or Viewgroup subclasses. </p> - -<p>In general, the XML vocabulary for declaring UI elements closely follows the structure and naming of the framework's UI-related classes and methods, where element names correspond to class names and attribute names correspond to methods. In fact, the correspondence is often so direct that you can guess what XML attribute corresponds to a class method, or guess what class corresponds to a given xml element. </p> - -<p>However, note that the XML vocabulary for defining UI is not entirely identical to the framework's classes and methods. In some cases, there are slight naming differences. For -example, the EditText element has a <code>text</code> attribute that corresponds to -<code>EditText.setText()</code>. </p> - -<div class="sidebox"><p>For your convenience, the API reference documentation for UI related classes lists the available XML attributes that correspond to the class methods, including inherited attributes.</p> - -<p>To learn more about the available XML elements and attributes, as well as the format of the XML file, see <a -href="{@docRoot}guide/topics/resources/available-resources.html#layoutresources">Layout Resources</a>.</p> - </div> - -<p>Using Android's XML vocabulary, you can quickly design UI layouts and the screen elements they contain, in the same way you create HTML files — as a series of nested tags. </p> - -<p>Each layout file must contain exactly one root element, and the root element must be a View or ViewGroup object. Once you've defined the root element, you can add additional layout objects or controls as child elements of the root element, if needed. In the example below, the tree of XML elements evaluates to the outermost LinearLayout object. - -<p>After you've declared your layout in XML, you must save the file, with the <code>.xml</code> extension, -in your application's <code>res/layout/</code> directory, so it will properly compile. </p> - -<p>When you compile your application, each XML layout file is compiled into an -android.view.View resource. You can then load the layout resource from your application code, by calling <code>setContentView(R.layout.<em>layout_file_name</em>)</code> in your {@link android.app.Activity#onCreate(android.os.Bundle) Activity.onCreate()} -implementation.</p> - -<p>When you load a layout resource, the Android system initializes run-time objects corresponding to the elements in your layout. It parses the elements of your layout in-order (depth-first), instantiating the Views and adding them to their parent(s). -See <a href="how-android-draws.html">How Android Draws Views</a> for more information.</p> - -<p>Attributes named <code>layout_<em>something</em></code> apply to that -object's LayoutParams member. <a href="{@docRoot}guide/topics/resources/available-resources.html#layoutresources">Layout -Resources</a> also describes how to learn the syntax for specifying -LayoutParams properties. </p> - -<p>Also note that Android draws elements in the order in which they -appear in the XML. Therefore, if elements overlap, the last one in the XML -file will probably be drawn on top of any previously listed elements in that -same space.</p> - -<p>The following values are supported for dimensions (described in {@link -android.util.TypedValue TypedValue}):</p> - -<ul> - <li>px (pixels) </li> - <li>dip (device independent pixels) </li> - <li>sp (scaled pixels — best for text size) </li> - <li>pt (points) </li> - <li>in (inches) </li> - <li>mm (millimeters) </li> -</ul> - -<p>Example: <code>android:layout_width="25px"</code> </p> - -<p>For more information about these dimensions, see <a href="{@docRoot}guide/topics/resources/available-resources.html#dimension">Dimension Values</a>.</p> - -<p>The example below shows an XML file and the resulting screen in the UI. Note that the text on the -top of the screen was set by calling {@link -android.app.Activity#setTitle(java.lang.CharSequence) Activity.setTitle}. Note -that the attributes that refer to relative elements (i.e., layout_toLeft) -refer to the ID using the syntax of a relative resource -(@id/<em>id_number</em>). </p> - -<table border="1"> - <tr> - <td> - <pre><?xml version="1.0" encoding="utf-8"?> -<!-- Demonstrates using a relative layout to create a form --> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:background="@drawable/blue" - android:padding="10px"> - - <TextView id="@+id/label" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="Type here:"/> - - <EditText id="@+id/entry" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:background="@android:drawable/editbox_background" - android:layout_below="@id/label"/> - - <Button id="@+id/ok" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_below="@id/entry" - android:layout_alignParentRight="true" - android:layout_marginLeft="10px" - android:text="OK" /> - - <Button android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toLeftOf="@id/ok" - android:layout_alignTop="@id/ok" - android:text="Cancel" /> -</RelativeLayout></pre></td> - <td><img src="{@docRoot}images/designing_ui_layout_example.png" alt="Screen shot showing how this layout XML file is rendered." /></td> - </tr> -</table> - - -<h2 id="LoadingTheResource">Loading the XML Resource</h2> -<p>Loading the compiled layout resource is very easy, and done with a single -call in the activity's <code>onCreate()</code> method, as shown here:</p> - -<pre> -protected void onCreate(Bundle savedInstanceState) -{ - // Be sure to call the super class. - super.onCreate(savedInstanceState); - - // Load the compiled layout resource into the window's - // default ViewGroup. - // The source file is res/layout/hello_activity.xml - setContentView(R.layout.hello_activity); - - // Retrieve any important stored values. - restoreValues(savedInstanceState); -} </pre> - -<h2 id="Position">Position</h2> - <p> - The geometry of a view is that of a rectangle. A view has a location, - expressed as a pair of <em>left</em> and <em>top</em> coordinates, and - two dimensions, expressed as a width and a height. The unit for location - and dimensions is the pixel. - </p> - - <p> - It is possible to retrieve the location of a view by invoking the methods - {@link android.view.View#getLeft()} and {@link android.view.View#getTop()}. The former returns the left, or X, - coordinate of the rectangle representing the view. The latter returns the - top, or Y, coordinate of the rectangle representing the view. These methods - both return the location of the view relative to its parent. For instance, - when getLeft() returns 20, that means the view is located 20 pixels to the - right of the left edge of its direct parent. - </p> - - <p> - In addition, several convenience methods are offered to avoid unnecessary - computations, namely {@link android.view.View#getRight()} and {@link android.view.View#getBottom()}. - These methods return the coordinates of the right and bottom edges of the - rectangle representing the view. For instance, calling {@link android.view.View#getRight()} - is similar to the following computation: <code>getLeft() + getWidth()</code>. - </p> - - -<h2 id="SizePaddingMargins">Size, Padding and Margins</h2> - <p> - The size of a view is expressed with a width and a height. A view actually - possess two pairs of width and height values. - </p> - - <p> - The first pair is known as <em>measured width</em> and - <em>measured height</em>. These dimensions define how big a view wants to be - within its parent. The - measured dimensions can be obtained by calling {@link android.view.View#getMeasuredWidth()} - and {@link android.view.View#getMeasuredHeight()}. - </p> - - <p> - The second pair is simply known as <em>width</em> and <em>height</em>, or - sometimes <em>drawing width</em> and <em>drawing height</em>. These - dimensions define the actual size of the view on screen, at drawing time and - after layout. These values may, but do not have to, be different from the - measured width and height. The width and height can be obtained by calling - {@link android.view.View#getWidth()} and {@link android.view.View#getHeight()}. - </p> - - <p> - To measure its dimensions, a view takes into account its padding. The padding - is expressed in pixels for the left, top, right and bottom parts of the view. - Padding can be used to offset the content of the view by a specific amount of - pixels. For instance, a left padding of 2 will push the view's content by - 2 pixels to the right of the left edge. Padding can be set using the - {@link android.view.View#setPadding(int, int, int, int)} method and queried by calling - {@link android.view.View#getPaddingLeft()}, {@link android.view.View#getPaddingTop()}, - {@link android.view.View#getPaddingRight()} and {@link android.view.View#getPaddingBottom()}. - </p> - - <p> - Even though a view can define a padding, it does not provide any support for - margins. However, view groups provide such a support. Refer to - {@link android.view.ViewGroup} and - {@link android.view.ViewGroup.MarginLayoutParams} for further information. - </p> -
\ No newline at end of file diff --git a/docs/html/guide/topics/views/how-android-draws.jd b/docs/html/guide/topics/views/how-android-draws.jd deleted file mode 100644 index f497db7..0000000 --- a/docs/html/guide/topics/views/how-android-draws.jd +++ /dev/null @@ -1,90 +0,0 @@ -page.title=How Android Draws Views -parent.title=Views and Layout -parent.link=index.html -@jd:body - - -<p>As mentioned in the introduction to <a href="index.html">Views and Layout</a>, -drawing begins when the Activity requests the root node of the layout to measure and -draw the layout tree. Drawing is handled by walking the tree and rendering each view that - intersects the invalid region. In turn, each view group is responsible for requesting -each of its children to be drawn and each view is responsible for drawing itself. - Because the tree is traversed in-order, - this means that parents will be drawn before (i.e., behind) their children, with - siblings drawn in the order they appear in the tree. - </p> - -<div class="sidebox"> - <p>The framework will not draw views that are not in the invalid region, and also - will take care of drawing the views background for you.</p> - <p>You can force a view to draw, by calling {@link android.view.View#invalidate()}. - </p> -</div> - -<p> - Drawing the layout is a two pass process: a measure pass and a layout pass. The measuring - pass is implemented in {@link android.view.View#measure(int, int)} and is a top-down traversal - of the view tree. Each view pushes dimension specifications down the tree - during the recursion. At the end of the measure pass, every view has stored - its measurements. The second pass happens in - {@link android.view.View#layout(int,int,int,int)} and is also top-down. During - this pass each parent is responsible for positioning all of its children - using the sizes computed in the measure pass. - </p> - - <p> - When a view's measure() method returns, its {@link android.view.View#getMeasuredWidth()} and - {@link android.view.View#getMeasuredHeight()} values must be set, along with those for all of - that view's descendants. A view's measured width and measured height values - must respect the constraints imposed by the view's parents. This guarantees - that at the end of the measure pass, all parents accept all of their - children's measurements. A parent view may call measure() more than once on - its children. For example, the parent may measure each child once with - unspecified dimensions to find out how big they want to be, then call - measure() on them again with actual numbers if the sum of all the children's - unconstrained sizes is too big or too small (i.e., if the children don't agree among themselves - as to how much space they each get, the parent will intervene and set the rules on the second pass). - </p> - - <div class="sidebox"><p> - To intiate a layout, call {@link android.view.View#requestLayout}. This method is typically - called by a view on itself when it believes that is can no longer fit within - its current bounds.</p> - </div> - - <p> - The measure pass uses two classes to communicate dimensions. The - {@link android.view.View.MeasureSpec} class is used by views to tell their parents how they - want to be measured and positioned. The base LayoutParams class just - describes how big the view wants to be for both width and height. For each - dimension, it can specify one of:</p> - <ul> - <li> an exact number - <li>FILL_PARENT, which means the view wants to be as big as its parent - (minus padding)</li> - <li> WRAP_CONTENT, which means that the view wants to be just big enough to - enclose its content (plus padding).</li> - </ul> - <p>There are subclasses of LayoutParams for different subclasses of ViewGroup. - For example, AbsoluteLayout has its own subclass of LayoutParams which adds - an X and Y value. - </p> - - <p> - MeasureSpecs are used to push requirements down the tree from parent to - child. A MeasureSpec can be in one of three modes:</p> - <ul> - <li>UNSPECIFIED: This is used by a parent to determine the desired dimension - of a child view. For example, a LinearLayout may call measure() on its child - with the height set to UNSPECIFIED and a width of EXACTLY 240 to find out how - tall the child view wants to be given a width of 240 pixels.</li> - <li>EXACTLY: This is used by the parent to impose an exact size on the - child. The child must use this size, and guarantee that all of its - descendants will fit within this size.</li> - <li>AT_MOST: This is used by the parent to impose a maximum size on the - child. The child must gurantee that it and all of its descendants will fit - within this size.</li> - </ul> - - - diff --git a/docs/html/guide/topics/views/index.jd b/docs/html/guide/topics/views/index.jd deleted file mode 100644 index a246ba1..0000000 --- a/docs/html/guide/topics/views/index.jd +++ /dev/null @@ -1,216 +0,0 @@ -page.title=Views and Layout -@jd:body - -<div id="qv-wrapper"> -<div id="qv"> - - <h2>Key classes and packages</h2> - <ol> - <li>{@link android.view.View}</li> - <li>{@link android.view.ViewGroup}</li> - <li>{@link android.widget}</li> - </ol> - - <h2>In this document</h2> - <ol> - <li><a href="#ViewHierarchy">View Hierarchy</a></li> - <li><a href="#Layout">Layout</a></li> - <li><a href="#Widgets">Widgets</a></li> - <li><a href="#Events">Events</a></li> - <li><a href="#Adapters">Adapters</a></li> - <li><a href="#StylesAndThemes">Styles and Themes</a></li> - </ol> -</div> -</div> - -<p>In an Android application, a user interface is built using {@link android.view.View} and -{@link android.view.ViewGroup} objects. There are many types of views and view groups, each of which -is a descendant of the {@link android.view.View} class.</p> - -<p>View objects are the basic units of user interface expression on the Android platform. -The View class serves as the base for subclasses called "widgets," which offer fully implemented -UI objects, like text fields and buttons. The ViewGroup class serves as the base for subclasses called "layouts," -which offer different kinds of layout architecture, like linear, tabular and relative.</p> - -<p>A View object is a data structure whose properties store the layout properties and content for a specific -rectangular area of the screen. A View object handles its own measurement, layout, drawing, focus change, -scrolling, and key/gesture interactions for the rectangular screen area it represents. </p> - - -<h2 id="ViewHierarchy">View Hierarchy</h2> - -<p>On the Android platform, you will define an Activity's UI using a hierarchy of view and view group nodes, -as shown in the diagram below. This hierarchy tree can be as simple or complex as you need it to be, and you -can build it up using Android's set of predefined widgets and layouts, or with custom view types that you -create yourself.</p> - -<img src="{@docRoot}images/viewgroup.png" alt="" width="312" height="211" align="center"/> - -<p>The Android system will notify your Activity when it becomes active and receives focus. -In order to attach the view hierarchy tree to the screen for rendering, your Activity must call its -<code>setContentView()</code> method and pass a reference to the root node object. The Android system -receives this reference so that it can invalidate, measure, and draw the tree. The root node requests -that its child nodes draw themselves — in turn, each view group node is responsible for -calling <code>Draw()</code> on each of its own child views, so that each child view can render itself. -The children may request a size and location within the parent, but the parent object has the final -decision on where how big each child can be. To learn more about how a view group and its children are measured -and drawn, read <a href="how-android-draws.html">How Android Draws Views</a>.</p> - - -<h2 id="Layout">Layout</h2> - -<p>The most common way to define your layout and express the view hierarchy is with an XML layout file. -XML offers a human-readable structure for the layout, much like HTML. Each element in XML is -(usually a descendant of) either a View or ViewGroup object. View objects are leaves in the tree, -ViewGroup objects are branches in the tree. The name of an XML element -is the respective class object name. So a <code><TextView></code> element creates -a {@link android.widget.TextView} widget in your UI, and a <code><LinearLayout></code> element creates -a {@link android.widget.LinearLayout} layout branch in the tree. To learn more about how to write your layout in XML, -read <a href="declaring-layout.html">Declaring and Querying Layout</a>. - -<div class="sidebox-wrapper"> -<div class="sidebox"> - <p><b>Tip:</b> You can also draw new views and view groups from within your code, - by adding new View and ViewGroup objects to an - existing ViewGroup (specifically, you'll use the <code>addView()</code> methods to dynamically insert new views). - To see how to add views in your code, see the {@link android.view.ViewGroup} reference.</p> -</div> -</div> - -<p>There are a variety of ways in which you can layout your views, using different view groups. -Some pre-defined view groups offered by Android (called layouts) include LinearLayout, RelativeLayout, AbsoluteLayout, -TableLayout, GridLayout and others. Each offers a different mechanisms for arranging child views -among each other. -To learn more about how to use some of these view groups for your layout, -read <a href="layout.html">Common Layout Objects</a>. - -<h3 id="IDs">IDs</h3> - -<p>Views may have an integer ID associated with them. The ID is written as a string, but once the application is -compiled, it will be referenced as an integer. -These IDs are typically assigned in the layout XML file as an attribute of the view, -and are used to uniquely identify a view within the tree. The usual syntax for an ID, inside an XML tag is:</p> -<pre>id="@+id/my_button"</pre> -<p>The at-symbol (@) at the beginning of the string indicates that the XML parser should parse and expand the rest -of the ID string and identify it as an ID resource. The plus-symbol (+) means that this is a new resource name that must -be created and added to our resources (in the <code>R.java</code> file). There are a number of other ID resources that -are offered by the Android framework. When referencing an Android resource ID, you do not need the plus-symbol, -but must add the <code>android</code> package namespace, like so:</p> -<pre>id="@android:id/empty"</pre> -<p>With the <code>android</code> package namespace in place, we're now referencing an ID from the <code>android.R</code> -resources class, rather than the local resources class.</p> - -<p>In order to create views and reference them from the application, a common pattern is to:</p> -<ol> - <li>Define a view/widget in the layout file and assign it a unique ID. E.g.: -<pre> -<Button id="@+id/my_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/my_button_text"/> -</pre> - </li> - <li>Then create an instance of the view object and capture it from the layout -(typically in the <code>onCreate()</code> method). -<pre> -Button myButton = (Button) findViewById(R.id.my_button); -</pre> - </li> -</ol> -<p>Defining IDs for view objects is important when creating a {@link android.widget.RelativeLayout}. -In a relative layout, sibling views can define their layout relative to another sibling view, -which is referenced by the unique ID.</p> -<p>An ID need not be unique throughout the entire tree, but it should be -unique within the part of the tree you are searching (which may often be the entire tree, so it's best -to be completely unique when possible).</p> - - -<h3>Layout Parameters</h3> - -<p>Every ViewGroup class implements a nested class that extends {@link -android.view.ViewGroup.LayoutParams}. This subclass -contains property types that define each child view's size and position, as -appropriate for that type of view group. As you can see in the figure below, the parent -view group defines layout parameters for each child view (including the child view group).</p> - -<img src="{@docRoot}images/layoutparams.png" alt="" height="300" align="center"/> - -<p>Note that every LayoutParams subclass has its own syntax for setting -values. Each child element must define LayoutParams that are appropriate for its parent, -though it may also define different LayoutParams for its own children. </p> - -<p>All view groups include a width and height, and each view is required to define them. -Many LayoutParams also include optional margins and -borders. You can specify width and height with exact measurements, though you probably won't want -to do this often. More often, you will tell your view to size itself either to -the dimensions required by its content, or to become as big as its parent view group -will allow (with the <var>wrap_content</var> and <var>fill_parent</var> values, respectively). -The accepted measurement types are defined in the -<a href="{@docRoot}guide/topics/resources/available-resources.html#dimension">Available Resources</a> document.</p> - -<h2 id="Widgets">Widgets</h2> - - -<p>The View class also serves as a base class for <em>widgets</em> — a set of fully implemented -View subclasses that draw interactive screen elements, so you can quickly build your UI. -Android provides a vast collection of widgets for special actions. -Some of them are basic interaction elements like buttons and text fields, while others are more complex, -like a date picker or zoom controls.</p> -<p>For a list of all built-in widgets, see the {@link android.widget widget}.</p> - -<p>You're not limited to the kinds of views, layouts and widgets provided by the Android platform. If you'd -like to do something more customized, create your own widget or layout, you can. -Read more in <a href="custom-components.html">Building Custom Components</a>. - - -<h2 id="Events">Events</h2> - -<p>Once you've designed and built your UI layout, you need to handle the user interaction with it. -Obviously, the views that you've implemented in the layout are the -receptors for such interaction events. Because the View class is built to listen for most interaction events, -receiving and handling them is pretty straigh-forward. When you want to perform an action upon an event, -you need to do one of two things:</p> -<ul> - <li>Override an existing callback method for the view you've implemented, which will be called when something -like a touch or focus event occurs.</li> - <li>Define a listener interface, like {@link android.view.View.OnClickListener} (for handling "clicks" on a View). -You must then define the listener for your view with the respective <code>set...Listener()</code> -method (such as {@link android.view.View#setOnClickListener(android.view.View.OnClickListener) setOnCLickListener()}).</li> -</ul> - -<p>To learn more about handling events and writing your own listeners, -read <a href="ui-events.html">Handling UI Events</a>.</p> - - -<h2 id="Adapters">Adapters</h2> - -<p>Sometimes you'll want to populate a view group with some information that can't be hard-coded, instead, -you want to bind your view to an external source of data. To do this, you use an AdapterView as -your view group and each child View is initialized and populated with data from the Adapter.</p> -<p>The AdapterView object is an implementation of ViewGroup that determines its child views -based on a given Adapter object. The Adapter acts like a courier between your data source (perhaps an -array of external strings) and the AdapterView, which displays it. There are several implementations -of the Adapter class, for specific tasks, such as the CursorAdapter for reading database data from a Cursor, -or an ArrayAdapter for reading from an arbitrary array.</p> -<p>To learn more about using an Adapter to populate your views, read -<a href="binding.html">Binding to Data with AdapterView</a>.</p> - - -<h2 id="StylesAndThemes">Styles and Themes</h2> - -<p>Perhaps you're not satisfied with the look of the standard widgets. To revise them, you can create some -of your own styles and themes.</p> - -<ul> - <li>A style is a set of one or more formatting attributes that you can apply as a unit to individual elements -in your layout. For example, you could define a style that specifies a certain text size and color, then -apply it to only specific View elements.</li> - <li>A theme is a set of one or more formatting attributes that you can apply as a unit to all activities in -an application, or just a single activity. For example, you could define a theme that sets specific colors for -the window frame and the panel background, and sets text sizes and colors for menus. This theme can then be -applied to specific activities or the entire application.</li> -</ul> - -<p>Styles and themes are resources. Android provides some default style and theme resources that you can use, -or you can declare your own custom style and theme resources. Learn more about using styles and themes in the -<a href="themes.html">Applying Styles and Themes</a> document.</p> diff --git a/docs/html/guide/topics/views/ui-events.jd b/docs/html/guide/topics/views/ui-events.jd deleted file mode 100644 index 96136f8..0000000 --- a/docs/html/guide/topics/views/ui-events.jd +++ /dev/null @@ -1,113 +0,0 @@ -page.title=Handling UI Events -parent.title=Views and Layout -parent.link=index.html -@jd:body - -<div id="qv-wrapper"> -<div id="qv"> - <h2>In this document</h2> - <ol> - <li><a href="#TouchMode">Touch Mode</a></li> - <li><a href="#Scrolling">Scrolling</a></li> - <li><a href="#EventCycle">Event Cycle</a></li> - </ol> - - <h2>See also</h2> - <ol> - <li><a href="{@docRoot}guide/tutorials/views/hello-formstuff.html">Hello Form Stuff tutorial</a></li> - </ol> -</div> -</div> - -<p>Many Android classes declare callback methods for handling relevant UI events such as keypresses, -touch events, focus changes, and so on. For example, {@link android.app.Activity Activity} provides -the methods <code>onKeyDown()</code> and <code>onKeyUp()</code> and {@link android.widget.TextView TextView} -provides <code>onFocusChanged()</code>. </p> - -<p>In most cases, you can handle events just by overriding the appropriate handler methods. -When an event is received, the Android system calls your handler method with the event data.</p> - -<p>However, some classes do not declare handler methods for specific events. For example, -{@link android.widget.Button} does not declare an <code>onClick()</code> handler method. So, to handle a click event, -you need to create an anonymous class to act as a listener for the event, then register the listener with the -target class object (via the appropriate <code>set...Listener()</code> method). The example below shows how to set -up a handler for click events in a Button object. </p> - -</p> -<pre>public class ExampleSendResult extends Activity -{ - protected void onCreate(Bundle savedValues) - { - ... - - // Capture our button from layout and listen for clicks. - Button button = (Button)findViewById(R.id.corky); - button.setOnClickListener(mCorkyListener); - } - - // Create an anonymous class to act as a button click listener. - private OnClickListener mCorkyListener = new OnClickListener() - { - public void onClick(View v) - { - //do something when the button is clicked - } - }; -} -</pre> - - -<h2 id="TouchMode">Touch Mode</h2> - <p> - When a user is navigating a user interface via directional keys such as a D-pad, it is - necessary to give focus to actionable items such as buttons so the user can see - what will take input. If the device has touch capabilities, however, and the user - begins interacting with the interface by touching it, it is no longer necessary to - always highlight, or give focus to, a particular view. Thus, there is a mode - for interaction named "touch mode." - </p> - <p> - For a touch-capable device, once the user touches the screen, the device - will enter touch mode. From this point onward, only views for which - {@link android.view.View#isFocusableInTouchMode} is true will be focusable, such as text editing widgets. - Other views that are touchable, like buttons, will not take focus when touched; they will - simply fire their on-click listeners when pressed. - </p> - <p> - Any time a user hits a directional key, such as a D-pad direction, the view device will - exit touch mode, and find a view to take focus, so that the user may resume interacting - with the user interface without touching the screen. - </p> - <p> - The touch mode state is maintained across {@link android.app.Activity}s. To query the current state, you can call - {@link android.view.View#isInTouchMode} to see whether the device is currently in touch mode. - </p> - - -<h2 id="Scrolling">Scrolling</h2> - <p> - The framework provides basic support for views that wish to internally - scroll their content. This includes keeping track of the X and Y scroll - offset as well as mechanisms for drawing scrollbars. See - {@link android.view.View#scrollBy(int, int)}, {@link android.view.View#scrollTo(int, int)} for more details. - </p> - -<h2 is="EventCycle">Event Cycle</h2> - <p>The basic cycle of a view is as follows:</p> - <ol> - <li>An event comes in and is dispatched to the appropriate view. The view - handles the event and notifies any listeners.</li> - <li>If, in the course of processing the event, the view's bounds may need - to be changed, the view will call {@link android.view.View#requestLayout()}.</li> - <li>Similarly, if in the course of processing the event the view's appearance - may need to be changed, the view will call {@link android.view.View#invalidate()}.</li> - <li>If either {@link android.view.View#requestLayout()} or {@link android.view.View#invalidate()} were called, - the framework will take care of measuring, laying out, and drawing the tree - as appropriate.</li> - </ol> - - <p class="note"><strong>Note:</strong> The entire view tree is single threaded. You must always be on - the UI thread when calling any method on any view. - If you are doing work on other threads and want to update the state of a view - from that thread, you should use a {@link android.os.Handler}. - </p>
\ No newline at end of file |