diff options
Diffstat (limited to 'docs/html/guide/topics/ui')
-rw-r--r-- | docs/html/guide/topics/ui/custom-components.jd | 2 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/dialogs.jd | 650 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/how-android-draws.jd | 4 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/index.jd | 2 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/layout-objects.jd | 16 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/notifiers/index.jd | 107 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/notifiers/notifications.jd | 432 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/notifiers/toasts.jd | 154 |
8 files changed, 1347 insertions, 20 deletions
diff --git a/docs/html/guide/topics/ui/custom-components.jd b/docs/html/guide/topics/ui/custom-components.jd index eccc2ca..76d1034 100644 --- a/docs/html/guide/topics/ui/custom-components.jd +++ b/docs/html/guide/topics/ui/custom-components.jd @@ -34,7 +34,7 @@ that you can use to construct your UI.</p> {@link android.widget.TextSwitcher TextSwitcher}. </p> <p>Among the layouts available are {@link android.widget.LinearLayout LinearLayout}, -{@link android.widget.FrameLayout FrameLayout}, {@link android.widget.AbsoluteLayout AbsoluteLayout}, +{@link android.widget.FrameLayout FrameLayout}, {@link android.widget.RelativeLayout RelativeLayout}, 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. diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd new file mode 100644 index 0000000..c0c0b1b --- /dev/null +++ b/docs/html/guide/topics/ui/dialogs.jd @@ -0,0 +1,650 @@ +page.title=Creating Dialogs +parent.title=User Interface +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> + <div id="qv"> + <h2>Key classes</h2> + <ol> + <li>{@link android.app.Dialog}</li> + </ol> + <h2>In this document</h2> + <ol> + <li><a href="#ShowingADialog">Showing a Dialog</a></li> + <li><a href="#DismissingADialog">Dismissing a Dialog</a></li> + <li><a href="#AlertDialog">Creating an AlertDialog</a> + <ol> + <li><a href="#AddingButtons">Adding buttons</a></li> + <li><a href="#AddingAList">Adding a list</a></li> + </ol> + </li> + <li><a href="#ProgressDialog">Creating a ProgressDialog</a> + <ol> + <li><a href="#ShowingAProgressBar">Showing a progress bar</a></li> + </ol> + </li> + <li><a href="#CustomDialog">Creating a Custom Dialog</a></li> + </ol> + </div> +</div> + +<p>A dialog is usually a small window that appears in front of the current Activity. +The underlying Activity loses focus and the dialog accepts all user interaction. +Dialogs are normally used +for notifications and short activities that directly relate to the application in progress.</p> + +<p>The Android API supports the following types of {@link android.app.Dialog} objects:</p> +<dl> + <dt>{@link android.app.AlertDialog}</dt> + <dd>A dialog that can manage zero, one, two, or three buttons, and/or a list of + selectable items that can include checkboxes or radio buttons. The AlertDialog + is capable of constructing most dialog user interfaces and is the suggested dialog type. + See <a href="#AlertDialog">Creating an AlertDialog</a> below.</dd> + <dt>{@link android.app.ProgressDialog}</dt> + <dd>A dialog that displays a progress wheel or progress bar. Because it's an extension of + the AlertDialog, it also supports buttons. + See <a href="#ProgressDialog">Creating a ProgressDialog</a> below.</dd> + <dt>{@link android.app.DatePickerDialog}</dt> + <dd>A dialog that allows the user to select a date. See the + <a href="{@docRoot}guide/tutorials/views/hello-datepicker.html">Hello DatePicker</a> tutorial.</dd> + <dt>{@link android.app.TimePickerDialog}</dt> + <dd>A dialog that allows the user to select a time. See the + <a href="{@docRoot}guide/tutorials/views/hello-timepicker.html">Hello TimePicker</a> tutorial.</dd> +</dl> + +<p>If you would like to customize your own dialog, you can extend the +base {@link android.app.Dialog} object or any of the subclasses listed above and define a new layout. +See the section on <a href="#CustomDialog">Creating a Custom Dialog</a> below.</p> + + +<h2 id="ShowingADialog">Showing a Dialog</h2> + +<p>A dialog is always created and displayed as a part of an {@link android.app.Activity}. +You should normally create dialogs from within your Activity's +{@link android.app.Activity#onCreateDialog(int)} callback method. +When you use this callback, the Android system automatically manages the state of +each dialog and hooks them to the Activity, effectively making it the "owner" of each dialog. +As such, each dialog inherits certain properties from the Activity. For example, when a dialog +is open, the Menu key reveals the options menu defined for the Activity and the volume +keys modify the audio stream used by the Activity.</p> + +<p class="note"><strong>Note:</strong> If you decide to create a dialog outside of the +<code>onCreateDialog()</code> method, it will not be attached to an Activity. You can, however, +attach it to an Activity with {@link android.app.Dialog#setOwnerActivity(Activity)}.</p> + +<p>When you want to show a dialog, call +{@link android.app.Activity#showDialog(int)} and pass it an integer that uniquely identifies the +dialog that you want to display.</p> + +<p>When a dialog is requested for the first time, Android calls +{@link android.app.Activity#onCreateDialog(int)} from your Activity, which is +where you should instantiate the {@link android.app.Dialog}. This callback method +is passed the same ID that you passed to {@link android.app.Activity#showDialog(int)}. +After you create the Dialog, return the object at the end of the method.</p> + +<p>Before the dialog is displayed, Android also calls the optional callback method +{@link android.app.Activity#onPrepareDialog(int,Dialog)}. Define this method if you want to change +any properties of the dialog each time it is opened. This method is called +every time a dialog is opened, whereas {@link android.app.Activity#onCreateDialog(int)} is only +called the very first time a dialog is opened. If you don't define +{@link android.app.Activity#onPrepareDialog(int,Dialog) onPrepareDialog()}, then the dialog will +remain the same as it was the previous time it was opened. This method is also passed the dialog's +ID, along with the Dialog object you created in {@link android.app.Activity#onCreateDialog(int) +onCreateDialog()}.</p> + +<p>The best way to define the {@link android.app.Activity#onCreateDialog(int)} and +{@link android.app.Activity#onPrepareDialog(int,Dialog)} callback methods is with a +<em>switch</em> statement that checks the <var>id</var> parameter that's passed into the method. +Each <em>case</em> should check for a unique dialog ID and then create and define the respective Dialog. +For example, imagine a game that uses two different dialogs: one to indicate that the game +has paused and another to indicate that the game is over. First, define an integer ID for +each dialog:</p> +<pre> +static final int DIALOG_PAUSED_ID = 0; +static final int DIALOG_GAMEOVER_ID = 1; +</pre> + +<p>Then, define the {@link android.app.Activity#onCreateDialog(int)} callback with a +switch case for each ID:</p> +<pre> +protected Dialog onCreateDialog(int id) { + Dialog dialog; + switch(id) { + case DIALOG_PAUSED_ID: + // do the work to define the pause Dialog + break; + case DIALOG_GAMEOVER_ID: + // do the work to define the game over Dialog + break; + default: + dialog = null; + } + return dialog; +} +</pre> + +<p class="note"><strong>Note:</strong> In this example, there's no code inside +the case statements because the procedure for defining your Dialog is outside the scope +of this section. See the section below about <a href="#AlertDialog">Creating an AlertDialog</a>, +offers code suitable for this example.</p> + +<p>When it's time to show one of the dialogs, call {@link android.app.Activity#showDialog(int)} +with the ID of a dialog:</p> +<pre> +showDialog(DIALOG_PAUSED_ID); +</pre> + + +<h2 id="DismissingADialog">Dismissing a Dialog</h2> + +<p>When you're ready to close your dialog, you can dismiss it by calling +{@link android.app.Dialog#dismiss()} on the Dialog object. +If necessary, you can also call {@link android.app.Activity#dismissDialog(int)} from the +Activity, which effectively calls {@link android.app.Dialog#dismiss()} on the +Dialog for you.</p> + +<p>If you are using {@link android.app.Activity#onCreateDialog(int)} to manage the state +of your dialogs (as discussed in the previous section), then every time your dialog is +dismissed, the state of the Dialog +object is retained by the Activity. If you decide that you will no longer need this object or +it's important that the state is cleared, then you should call +{@link android.app.Activity#removeDialog(int)}. This will remove any internal references +to the object and if the dialog is showing, it will dismiss it.</p> + +<h3>Using dismiss listeners</h3> + +<p>If you'd like your applcation to perform some procedures the moment that a dialog is dismissed, +then you should attach an on-dismiss listener to your Dialog.</p> + +<p>First define the {@link android.content.DialogInterface.OnDismissListener} interface. +This interface has just one method, +{@link android.content.DialogInterface.OnDismissListener#onDismiss(DialogInterface)}, which +will be called when the dialog is dismissed. +Then simply pass your OnDismissListener implementation to +{@link android.app.Dialog#setOnDismissListener(DialogInterface.OnDismissListener) +setOnDismissListener()}.</p> + +<p>However, note that dialogs can also be "cancelled." This is a special case that indicates +the dialog was explicitly cancelled by the user. This will occur if the user presses the +"back" button to close the dialog, or if the dialog explicitly calls {@link android.app.Dialog#cancel()} +(perhaps from a "Cancel" button in the dialog). When a dialog is cancelled, +the OnDismissListener will still be notified, but if you'd like to be informed that the dialog +was explicitly cancelled (and not dismissed normally), then you should register +an {@link android.content.DialogInterface.OnCancelListener} with +{@link android.app.Dialog#setOnCancelListener(DialogInterface.OnCancelListener) +setOnCancelListener()}.</p> + + +<h2 id="AlertDialog">Creating an AlertDialog</h2> + +<p>An {@link android.app.AlertDialog} is an extension of the {@link android.app.Dialog} +class. It is capable of constructing most dialog user interfaces and is the suggested dialog type. +You should use it for dialogs that use any of the following features:</p> +<ul> + <li>A title</li> + <li>A text message</li> + <li>One, two, or three buttons</li> + <li>A list of selectable items (with optional checkboxes or radio buttons)</li> +</ul> + +<p>To create an AlertDialog, use the {@link android.app.AlertDialog.Builder} subclass. +Get a Builder with {@link android.app.AlertDialog.Builder#AlertDialog.Builder(Context)} and +then use the class's public methods to define all of the +AlertDialog properties. After you're done with the Builder, retrieve the +AlertDialog object with {@link android.app.AlertDialog.Builder#create()}.</p> + +<p>The following topics show how to define various properties of the AlertDialog using the +AlertDialog.Builder class. If you use any of the following sample code inside your +{@link android.app.Activity#onCreateDialog(int) onCreateDialog()} callback method, +you can return the resulting Dialog object to display the dialog.</p> + + +<h3 id="AddingButtons">Adding buttons</h3> + +<img src="{@docRoot}images/dialog_buttons.png" alt="" style="float:right" /> + +<p>To create an AlertDialog with side-by-side buttons like the one shown in the screenshot to the right, +use the <code>set...Button()</code> methods:</p> + +<pre> +AlertDialog.Builder builder = new AlertDialog.Builder(this); +builder.setMessage("Are you sure you want to exit?") + .setCancelable(false) + .setPositiveButton("Yes", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + MyActivity.this.finish(); + } + }) + .setNegativeButton("No", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); +AlertDialog alert = builder.create(); +</pre> + +<p>First, add a message for the dialog with +{@link android.app.AlertDialog.Builder#setMessage(CharSequence)}. Then, begin +method-chaining and set the dialog +to be <em>not cancelable</em> (so the user cannot close the dialog with the back button) +with {@link android.app.AlertDialog.Builder#setCancelable(boolean)}. For each button, +use one of the <code>set...Button()</code> methods, such as +{@link android.app.AlertDialog.Builder#setPositiveButton(CharSequence,DialogInterface.OnClickListener) +setPositiveButton()}, that accepts the name for the button and a +{@link android.content.DialogInterface.OnClickListener} that defines the action to take +when the user selects the button.</p> + +<p class="note"><strong>Note:</strong> You can only add one of each button type to the +AlertDialog. That is, you cannot have more than one "positive" button. This limits the number +of possible buttons to three: positive, neutral, and negative. These names are technically irrelevant to the +actual functionality of your buttons, but should help you keep track of which one does what.</p> + + +<h3 id="AddingAList">Adding a list</h3> + +<img src="{@docRoot}images/dialog_list.png" alt="" style="float:right" /> + +<p>To create an AlertDialog with a list of selectable items like the one shown to the right, +use the <code>setItems()</code> method:</p> + +<pre> +final CharSequence[] items = {"Red", "Green", "Blue"}; + +AlertDialog.Builder builder = new AlertDialog.Builder(this); +builder.setTitle("Pick a color"); +builder.setItems(items, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); + } +}); +AlertDialog alert = builder.create(); +</pre> + +<p>First, add a title to the dialog with +{@link android.app.AlertDialog.Builder#setTitle(CharSequence)}. +Then, add a list of selectable items with +{@link android.app.AlertDialog.Builder#setItems(CharSequence[],DialogInterface.OnClickListener) +setItems()}, which accepts the array of items to display and a +{@link android.content.DialogInterface.OnClickListener} that defines the action to take +when the user selects an item.</p> + + +<h4>Adding checkboxes and radio buttons</h4> + +<img src="{@docRoot}images/dialog_singlechoicelist.png" alt="" style="float:right" /> + +<p>To create a list of multiple-choice items (checkboxes) or +single-choice items (radio buttons) inside the dialog, use the +{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String, +DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} and +{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) +setSingleChoiceItems()} methods, respectively. +If you create one of these selectable lists in the +{@link android.app.Activity#onCreateDialog(int) onCreateDialog()} callback method, +Android manages the state of the list for you. As long as the Activity is active, +the dialog remembers the items that were previously selected, but when the user exits the +Activity, the selection is lost. + +<p class="note"><strong>Note:</strong> To save the selection when the user leaves or +pauses the Activity, you must properly save and restore the setting throughout +the <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Activity Lifecycle</a>. +To permanently save the selections, even when the Activity process is completely shutdown, +you need to save the settings +with one of the <a href="{@docRoot}guide/topics/data/data-storage.html">Data +Storage</a> techniques.</p> + +<p>To create an AlertDialog with a list of single-choice items like the one shown to the right, +use the same code from the previous example, but replace the <code>setItems()</code> method with +{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) +setSingleChoiceItems()}:</p> + +<pre> +final CharSequence[] items = {"Red", "Green", "Blue"}; + +AlertDialog.Builder builder = new AlertDialog.Builder(this); +builder.setTitle("Pick a color"); +builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); + } +}); +AlertDialog alert = builder.create(); +</pre> + +<p>The second parameter in the +{@link android.app.AlertDialog.Builder#setSingleChoiceItems(CharSequence[],int,DialogInterface.OnClickListener) +setSingleChoiceItems()} method is an integer value for the <var>checkedItem</var>, which indicates the +zero-based list position of the default selected item. Use "-1" to indicate that no item should be +selected by default.</p> + + +<h2 id="ProgressDialog">Creating a ProgressDialog</h2> + +<img src="{@docRoot}images/dialog_progress_spinning.png" alt="" style="float:right" /> + +<p>A {@link android.app.ProgressDialog} is an extension of the {@link android.app.AlertDialog} +class that can display a progress animation in the form of a spinning wheel, for a task with +progress that's undefined, or a progress bar, for a task that has a defined progression. +The dialog can also provide buttons, such as one to cancel a download.</p> + +<p>Opening a progress dialog can be as simple as calling +{@link android.app.ProgressDialog#show(Context,CharSequence,CharSequence) +ProgressDialog.show()}. For example, the progress dialog shown to the right can be +easily achieved without managing the dialog through the +{@link android.app.Activity#onCreateDialog(int)} callback, +as shown here:</p> + +<pre> +ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", + "Loading. Please wait...", true); +</pre> + +<p>The first parameter is the application {@link android.content.Context}, +the second is a title for the dialog (left empty), the third is the message, +and the last parameter is whether the progress +is indeterminate (this is only relevant when creating a progress bar, which is +discussed in the next section). +</p> + +<p>The default style of a progress dialog is the spinning wheel. +If you want to create a progress bar that shows the loading progress with granularity, +some more code is required, as discussed in the next section.</p> + + +<h3 id="ShowingAProgressBar">Showing a progress bar</h3> + +<img src="/images/dialog_progress_bar.png" alt="" style="float:right" /> + +<p>To show the progression with an animated progress bar:</p> + +<ol> + <li>Initialize the + ProgressDialog with the class constructor, + {@link android.app.ProgressDialog#ProgressDialog(Context)}.</li> + <li>Set the progress style to "STYLE_HORIZONTAL" with + {@link android.app.ProgressDialog#setProgressStyle(int)} and + set any other properties, such as the message.</li> + <li>When you're ready to show the dialog, call + {@link android.app.Dialog#show()} or return the ProgressDialog from the + {@link android.app.Activity#onCreateDialog(int)} callback.</li> + <li>You can increment the amount of progress displayed + in the bar by calling either {@link android.app.ProgressDialog#setProgress(int)} with a value for + the total percentage completed so far or {@link android.app.ProgressDialog#incrementProgressBy(int)} + with an incremental value to add to the total percentage completed so far.</li> +</ol> + +<p>For example, your setup might look like this:</p> +<pre> +ProgressDialog progressDialog; +progressDialog = new ProgressDialog(mContext); +progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); +progressDialog.setMessage("Loading..."); +progressDialog.setCancelable(false); +</pre> + +<p>The setup is simple. Most of the code needed to create a progress dialog is actually +involved in the process that updates it. You might find that it's +necessary to create a second thread in your application for this work and then report the progress +back to the Activity's UI thread with a {@link android.os.Handler} object. +If you're not familiar with using additional +threads with a Handler, see the example Activity below that uses a second thread to +increment a progress dialog managed by the Activity.</p> + +<script type="text/javascript"> +function toggleDiv(link) { + var toggleable = $(link).parent(); + if (toggleable.hasClass("closed")) { + $(".toggleme", toggleable).slideDown("fast"); + toggleable.removeClass("closed"); + toggleable.addClass("open"); + $(".toggle-img", toggleable).attr("title", "hide").attr("src", "/assets/images/triangle-opened.png"); + } else { + $(".toggleme", toggleable).slideUp("fast"); + toggleable.removeClass("open"); + toggleable.addClass("closed"); + $(".toggle-img", toggleable).attr("title", "show").attr("src", "/assets/images/triangle-closed.png"); + } + return false; +} +</script> +<style> +.toggleme { + padding:0 0 1px 0; +} +.toggleable a { + text-decoration:none; +} +.toggleable.closed .toggleme { + display:none; +} +#jd-content .toggle-img { + margin:0; +} +</style> + +<div class="toggleable closed"> + <a href="#" onclick="return toggleDiv(this)"> + <img src="/assets/images/triangle-closed.png" class="toggle-img" /> + <strong>Example ProgressDialog with a second thread</strong></a> + <div class="toggleme"> + <p>This example uses a second thread to track the progress of a process (which actually just +counts up to 100). The thread sends a {@link android.os.Message} back to the main +Activity through a {@link android.os.Handler} each time progress is made. The main Activity then updates the +ProgressDialog.</p> + +<pre> +package com.example.progressdialog; + +import android.app.Activity; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; + +public class NotificationTest extends Activity { + static final int PROGRESS_DIALOG = 0; + Button button; + ProgressThread progressThread; + ProgressDialog progressDialog; + + /** Called when the activity is first created. */ + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + // Setup the button that starts the progress dialog + button = (Button) findViewById(R.id.progressDialog); + button.setOnClickListener(new OnClickListener(){ + public void onClick(View v) { + showDialog(PROGRESS_DIALOG); + } + }); + } + + protected Dialog onCreateDialog(int id) { + switch(id) { + case PROGRESS_DIALOG: + progressDialog = new ProgressDialog(NotificationTest.this); + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + progressDialog.setMessage("Loading..."); + progressThread = new ProgressThread(handler); + progressThread.start(); + return progressDialog; + default: + return null; + } + } + + // Define the Handler that receives messages from the thread and update the progress + final Handler handler = new Handler() { + public void handleMessage(Message msg) { + int total = msg.getData().getInt("total"); + progressDialog.setProgress(total); + if (total >= 100){ + dismissDialog(PROGRESS_DIALOG); + progressThread.setState(ProgressThread.STATE_DONE); + } + } + }; + + /** Nested class that performs progress calculations (counting) */ + private class ProgressThread extends Thread { + Handler mHandler; + final static int STATE_DONE = 0; + final static int STATE_RUNNING = 1; + int mState; + int total; + + ProgressThread(Handler h) { + mHandler = h; + } + + public void run() { + mState = STATE_RUNNING; + total = 0; + while (mState == STATE_RUNNING) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + Log.e("ERROR", "Thread Interrupted"); + } + Message msg = mHandler.obtainMessage(); + Bundle b = new Bundle(); + b.putInt("total", total); + msg.setData(b); + mHandler.sendMessage(msg); + total++; + } + } + + /* sets the current state for the thread, + * used to stop the thread */ + public void setState(int state) { + mState = state; + } + } +} +</pre> + </div> <!-- end toggleme --> +</div> <!-- end toggleable --> + + + +<h2 id="CustomDialog">Creating a Custom Dialog</h2> + +<img src="{@docRoot}images/dialog_custom.png" alt="" style="float:right" /> + +<p>If you want a customized design for a dialog, you can create your own layout +for the dialog window with layout and widget elements. +After you've defined your layout, pass the root View object or +layout resource ID to {@link android.app.Dialog#setContentView(View)}.</p> + +<p>For example, to create the dialog shown to the right:</p> + +<ol> + <li>Create an XML layout saved as <code>custom_dialog.xml</code>: +<pre> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/layout_root" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:padding="10dp" + > + <ImageView android:id="@+id/image" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_marginRight="10dp" + /> + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:textColor="#FFF" + /> +</LinearLayout> +</pre> + + <p>This XML defines an {@link android.widget.ImageView} and a {@link android.widget.TextView} + inside a {@link android.widget.LinearLayout}.</p> + <li>Set the above layout as the dialog's content view and define the content + for the ImageView and TextView elements:</p> +<pre> +Context mContext = getApplicationContext(); +Dialog dialog = new Dialog(mContext); + +dialog.setContentView(R.layout.custom_dialog); +dialog.setTitle("Custom Dialog"); + +TextView text = (TextView) dialog.findViewById(R.id.text); +text.setText("Hello, this is a custom dialog!"); +ImageView image = (ImageView) dialog.findViewById(R.id.image); +image.setImageResource(R.drawable.android); +</pre> + + <p>After you instantiate the Dialog, set your custom layout as the dialog's content view with + {@link android.app.Dialog#setContentView(int)}, passing it the layout resource ID. + Now that the Dialog has a defined layout, you can capture View objects from the layout with + {@link android.app.Dialog#findViewById(int)} and modify their content.</p> + </li> + + <li>That's it. You can now show the dialog as described in + <a href="#ShowingADialog">Showing A Dialog</a>.</li> +</ol> + +<p>A dialog made with the base Dialog class must have a title. If you don't call +{@link android.app.Dialog#setTitle(CharSequence) setTitle()}, then the space used for the title +remains empty, but still visible. If you don't want +a title at all, then you should create your custom dialog using the +{@link android.app.AlertDialog} class. However, because an AlertDialog is created easiest with +the {@link android.app.AlertDialog.Builder} class, you do not have access to the +{@link android.app.Dialog#setContentView(int)} method used above. Instead, you must use +{@link android.app.AlertDialog.Builder#setView(View)}. This method accepts a {@link android.view.View} object, +so you need to inflate the layout's root View object from +XML.</p> + +<p>To inflate the XML layout, retrieve the {@link android.view.LayoutInflater} with +{@link android.app.Activity#getLayoutInflater()} +(or {@link android.content.Context#getSystemService(String) getSystemService()}), +and then call +{@link android.view.LayoutInflater#inflate(int, ViewGroup)}, where the first parameter +is the layout resource ID and the second is the ID of the root View. At this point, you can use +the inflated layout to find View objects in the layout and define the content for the +ImageView and TextView elements. Then instantiate the AlertDialog.Builder and set the +inflated layout for the dialog with {@link android.app.AlertDialog.Builder#setView(View)}.</p> + +<p>Here's an example, creating a custom layout in an AlertDialog:</p> + +<pre> +AlertDialog.Builder builder; +AlertDialog alertDialog; + +Context mContext = getApplicationContext(); +LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER); +View layout = inflater.inflate(R.layout.custom_dialog, + (ViewGroup) findViewById(R.id.layout_root)); + +TextView text = (TextView) layout.findViewById(R.id.text); +text.setText("Hello, this is a custom dialog!"); +ImageView image = (ImageView) layout.findViewById(R.id.image); +image.setImageResource(R.drawable.android); + +builder = new AlertDialog.Builder(mContext); +builder.setView(layout); +alertDialog = builder.create(); +</pre> + +<p>Using an AlertDialog for your custom layout lets you +take advantage of built-in AlertDialog features like managed buttons, +selectable lists, a title, an icon and so on.</p> + +<p>For more information, refer to the reference documentation for the +{@link android.app.Dialog} and {@link android.app.AlertDialog.Builder} +classes.</p> + + + diff --git a/docs/html/guide/topics/ui/how-android-draws.jd b/docs/html/guide/topics/ui/how-android-draws.jd index a511005..21f9833 100644 --- a/docs/html/guide/topics/ui/how-android-draws.jd +++ b/docs/html/guide/topics/ui/how-android-draws.jd @@ -70,8 +70,8 @@ and each View is responsible for drawing itself. 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. + For example, RelativeLayout has its own subclass of LayoutParams, which includes + the ability to center child Views horizontally and vertically. </p> <p> diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd index 6bd1d15..ef23672 100644 --- a/docs/html/guide/topics/ui/index.jd +++ b/docs/html/guide/topics/ui/index.jd @@ -116,7 +116,7 @@ complex layout.</p> <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, +Some pre-defined view groups offered by Android (called layouts) include LinearLayout, RelativeLayout, 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, diff --git a/docs/html/guide/topics/ui/layout-objects.jd b/docs/html/guide/topics/ui/layout-objects.jd index cf85fd6..bb13a18 100644 --- a/docs/html/guide/topics/ui/layout-objects.jd +++ b/docs/html/guide/topics/ui/layout-objects.jd @@ -10,7 +10,6 @@ parent.link=index.html <li><a href="#framelayout">FrameLayout</a></li> <li><a href="#linearlayout">LinearLayout</a></li> <li><a href="#tablelayout">TableLayout</a></li> - <li><a href="#absolutelayout">AbsoluteLayout</a></li> <li><a href="#relativelayout">RelativeLayout</a></li> <li><a href="#viewgroupsummary">Summary of Important View Groups</a></li> </ol> @@ -143,16 +142,6 @@ documentation for more details. </p> TableLayout</a> tutorial.</p> -<h2 id="absolutelayout">AbsoluteLayout</h2> -<p>{@link android.widget.AbsoluteLayout} enables child views to specify - their own exact x/y coordinates on the screen. Coordinates <em>(0,0)</em> is the upper left - corner, and values increase as you move down and to the right. Margins are not - supported, and overlapping elements are allowed (although not recommended). We - generally recommend against using AbsoluteLayout unless you have good reasons - to use it, because it is fairly rigid and does not adjust to different types of - displays. </p> - - <h2 id="relativelayout">RelativeLayout</h2> <p>{@link android.widget.RelativeLayout} lets child views specify their position relative to the parent view or to each other (specified by ID). So you can @@ -232,11 +221,6 @@ RelativeLayout</a> tutorial.</p> <th scope="col">Description</th> </tr> <tr> - <td>{@link android.widget.AbsoluteLayout AbsoluteLayout}<br /></td> - <td>Enables you to specify the location of child objects relative to the - parent in exact measurements (for example, pixels). </td> - </tr> - <tr> <td>{@link android.widget.FrameLayout FrameLayout}</td> <td>Layout that acts as a view frame to display a single object. </td> diff --git a/docs/html/guide/topics/ui/notifiers/index.jd b/docs/html/guide/topics/ui/notifiers/index.jd new file mode 100644 index 0000000..5b37f5b6 --- /dev/null +++ b/docs/html/guide/topics/ui/notifiers/index.jd @@ -0,0 +1,107 @@ +page.title=Notifying the User +@jd:body + +<div id="qv-wrapper"> + <div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#Toast">Toast Notification</a></li> + <li><a href="#StatusBarNotification">Status Bar Notification</a></li> + <li><a href="#Dialog">Dialog Notification</a></li> + </ol> + <h2>More about</h2> + <ol> + <li><a href="toasts.html">Creating Toast Notifications</a></li> + <li><a href="notifications.html">Creating Status Bar Notifications</a></li> + <li><a href="{@docRoot}guide/topics/ui/dialogs.html">Creating Dialogs</a></li> + </ol> + </div> +</div> + +<p>Several types of situations may arise that require you to notify the user +about an event that occurs in your application. Some events require the user to respond +and others do not. For example:</p> +<ul> + <li>When an event such as saving a file is complete, a small message +should appear to confirm that the save was successful.</li> + <li>If the application is running in the background and needs the user's attention, +the application should create a notificaiton that allows the user to respond at +his or her convenience.</li> + <li>If the application is +performing work that the user must wait for (such as loading a file), +the application should show a hovering progress wheel or bar.</li> +</ul> + +<p>Each of these notification tasks can be achieved using a different technique:</p> +<ul> + <li>A <a href="#Toast">Toast Notification</a>, for brief messages that come + from the background.</li> + <li>A <a href="#StatusBar">Status Bar Notification</a>, for persistent reminders + that come from the background and request the user's response.</li> + <li>A <a href="#Dialog">Dialog Notification</a>, for Activity-related notifications.</li> +</ul> + +<p>This document summarizes each of these techniques for notifying the user and includes +links to full documentation.</p> + + +<h2 id="Toast">Toast Notification</h2> + +<img src="{@docRoot}images/toast.png" alt="" style="float:right" /> + +<p>A toast notificaiton is a message that pops up on the surface of the window. +It only fills the amount of space required for the message and the user's current +activity remains visible and interactive. The notification automatically fades in and +out, and does not accept interaction events. Because a toast can be created from a background +{@link android.app.Service}, it appears even if the application isn't visible.</p> + +<p>A toast is best for short text messages, such as "File saved," +when you're fairly certain the user is paying attention +to the screen. A toast can not accept user interaction events; if you'd like +the user to respond and take action, consider using a +<a href="#StatusBar">Status Bar Notification</a> instead.</p> + +<p>For more information, refer to <a href="toasts.html">Creating Toast Notifications</a>.</p> + + +<h2 id="StatusBar">Status Bar Notification</h2> + +<img src="{@docRoot}images/notifications_window.png" alt="" style="float:right; clear:right;" /> + +<p>A status bar notification adds an icon to the system's status bar +(with an optional ticker-text message) and an expanded message in the "Notifications" window. +When the user selects the expanded message, Android fires an +{@link android.content.Intent} that is defined by the notification (usually to launch an +{@link android.app.Activity}). +You can also configure the notification to alert the user with a sound, a vibration, and flashing +lights on the device.</p> + +<p>This kind of notification is ideal when your application is working in +a background {@link android.app.Service} and needs to +notify the user about an event. If you need to alert the user about an event that occurs +while your Activity is still in focus, consider using a +<a href="#Dialog">Dialog Notification</a> instead.</p> + +<p>For more information, refer to +<a href="notifications.html">Creating Status Bar Notifications</a>.</p> + + +<h2 id="Dialog">Dialog Notification</h2> + +<img src="{@docRoot}images/dialog_progress_spinning.png" alt="" style="float:right" /> + +<p>A dialog is usually a small window that appears in front of the current Activity. +The underlying Activity loses focus and the dialog accepts all user interaction. +Dialogs are normally used +for notifications and short activities that directly relate to the application in progress.</p> + +<p>You should use a dialog when you need to show a progress bar or a short +message that requires confirmation from the user (such as an alert with "OK" and "Cancel" buttons). +You can use also use dialogs as integral componenents +in your application's UI and for other purposes besides notifications. +For a complete discussion on all the available types of dialogs, +including its uses for notifications, refer to +<a href="{@docRoot}guide/topics/ui/dialogs.html">Creating Dialogs</a>.</p> + + + diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd new file mode 100644 index 0000000..e6fa48f --- /dev/null +++ b/docs/html/guide/topics/ui/notifiers/notifications.jd @@ -0,0 +1,432 @@ +page.title=Creating Status Bar Notifications +parent.title=Notifying the User +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> + <div id="qv"> + <h2>Key classes</h2> + <ol> + <li>{@link android.app.Notification}</li> + <li>{@link android.app.NotificationManager}</li> + </ol> + <h2>In this document</h2> + <ol> + <li><a href="#Basics">The Basics</a></li> + <li><a href="#ManageYourNotifications">Managing your Notifications</a></li> + <li><a href="#CreateANotification">Creating a Notification</a> + <ol> + <li><a href="#Update">Updating the notification</a></li> + <li><a href="#Sound">Adding a sound</a></li> + <li><a href="#Vibration">Adding vibration</a></li> + <li><a href="#Lights">Adding flashing lights</a></li> + <li><a href="#More">More features</a></li> + </ol> + </li> + <li><a href="#CustomExpandedView">Creating a Custom Expanded View</a></li> + </ol> + </div> +</div> + +<p>A status bar notification adds an icon to the system's status bar +(with an optional ticker-text message) and an expanded message in the "Notifications" window. +When the user selects the expanded message, Android fires an +{@link android.content.Intent} that is defined by the notification (usually to launch an +{@link android.app.Activity}). +You can also configure the notification to alert the user with a sound, a vibration, and flashing +lights on the device.</p> + +<p>A status bar notification should be used for any case in +which a background Service needs to alert the user about an event that requires a response. A background Service +<strong>should never</strong> launch an Activity on its own in order to receive user interaction. +The Service should instead create a status bar notification that will launch the Activity +when selected by the user.</p> + +<p>The screenshot below shows the status bar with a notification icon on the left side.</p> +<img src="{@docRoot}images/status_bar.png" alt="" /> + +<p>The next screenshot shows the notification's expanded message in the "Notifications" window. +The user can reveal the Notifications window by pulling down the status bar +(or selecting <em>Notifications</em> from the Home options menu).</p> +<img src="{@docRoot}images/notifications_window.png" alt="" /> + + +<h2 id="Basics">The Basics</h2> + +<p>An {@link android.app.Activity} or {@link android.app.Service} can initiate a status bar +notification. Because an Activity can perform actions only while it is +active and in focus, you should create your status bar notifications from a +Service. This way, the notification can be created from the background, +while the user is using another application or +while the device is asleep. To create a notification, you must use two +classes: {@link android.app.Notification} and {@link android.app.NotificationManager}.</p> + +<p>Use an instance of the {@link android.app.Notification} class to define the properties of your +status bar notification, such as the status bar icon, the expanded message, and extra settings such +as a sound to play. The {@link android.app.NotificationManager} is an Android system service that +executes and manages all Notifications. You do not instantiate the NotificationManager. In order +to give it your Notification, you must retrieve a reference to the NotificationManager with +{@link android.app.Activity#getSystemService(String) getSystemService()} and +then, when you want to notify the user, pass it your Notification object with +{@link android.app.NotificationManager#notify(int,Notification) notify()}. </p> + +<p>To create a status bar notification:</p> +<ol> + <li>Get a reference to the NotificationManager: +<pre> +String ns = Context.NOTIFICATION_SERVICE; +NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); +</pre> + </li> + <li>Instantiate the Notification: +<pre> +int icon = R.drawable.notification_icon; +CharSequence tickerText = "Hello"; +long when = System.currentTimeMillis(); + +Notification notification = new Notification(icon, tickerText, when); +</pre> + </li> + <li>Define the Notification's expanded message and Intent: +<pre> +Context context = getApplicationContext(); +CharSequence contentTitle = "My notification"; +CharSequence contentText = "Hello World!"; +Intent notificationIntent = new Intent(this, MyClass.class); +PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); + +notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); +</pre> + </li> + <li>Pass the Notification to the NotificationManager: +<pre> +private static final int HELLO_ID = 1; + +mNotificationManager.notify(HELLO_ID, notification); +</pre> + <p>That's it. Your user has now been notified.</p> + </li> +</ol> + + +<h2 id="ManageYourNotifications">Managing your Notifications</h2> + +<p>The {@link android.app.NotificationManager} is a system service that manages all +notifications. You must retrieve a reference to it with the +{@link android.app.Activity#getSystemService(String) getSystemService()} method. +For example:</p> +<pre> +String ns = Context.NOTIFICATION_SERVICE; +NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); +</pre> + +<p>When you want to send your status bar notification, pass the Notification object +to the NotificationManager with {@link android.app.NotificationManager#notify(int,Notification)}. +The first parameter is the unique ID for the Notification and the second is the Notification object. +The ID uniquely identifies the Notification from within your +application. This is necessary if you need to update the Notification or (if +your application manages different kinds of Notifications) select the appropriate action +when the user returns to your application via the Intent defined in the Notification.</p> + +<p>To clear the status bar notification when the user selects it from the Notifications +window, add the "FLAG_AUTO_CANCEL" flag to your Notification object. You can also clear it +manually with {@link android.app.NotificationManager#cancel(int)}, passing it the notification ID, +or clear all your Notifications with {@link android.app.NotificationManager#cancelAll()}.</p> + + +<h2 id="CreateANotification">Creating a Notification</h2> + +<p>A {@link android.app.Notification} object defines the details of the notification +message that is displayed in the status bar and "Notifications" window, and any other +alert settings, such as sounds and blinking lights.</p> + +<p>A status bar notification <em>requires</em> all of the following:</p> +<ul> + <li>An icon for the status bar</li> + <li>A title and expanded message for the expanded view (unless you define a + <a href="#CustomExpandedView">custom expanded view</a>)</li> + <li>A {@link android.app.PendingIntent}, to be fired when the notification is selected</li> +</ul> +<p>Optional settings for the status bar notification include:</p> +<ul> + <li>A ticker-text message for the status bar</li> + <li>An alert sound</li> + <li>A vibrate setting</li> + <li>A flashing LED setting</li> +</ul> + +<p>The starter-kit for a new Notification includes the +{@link android.app.Notification#Notification(int,CharSequence,long)} constructor and the +{@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)} +method. These define all the required settings for a Notification. +The following snippet demonstrates a basic Notification setup:</p> +<pre> +int icon = R.drawable.notification_icon; // icon from resources +CharSequence tickerText = "Hello"; // ticker-text +long when = System.currentTimeMillis(); // notification time +Context context = getApplicationContext(); // application Context +CharSequence contentTitle = "My notification"; // expanded message title +CharSequence contentText = "Hello World!"; // expanded message text + +Intent notificationIntent = new Intent(this, MyClass.class); +PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); + +// the next two lines initialize the Notification, using the configurations above +Notification notification = new Notification(icon, tickerText, when); +notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); +</pre> + + +<h3 id="Updating">Updating the notification</h3> + +<p>You can update the information in your status bar notification as events +continue to occur in your application. For example, when a new SMS text message arrives +before previous messages have been read, the Messaging application updates the existing +notification to display the total number of new messages received. +This practice of updating an existing Notification is much better than adding new Notifications +to the NotificationManager because it avoids clutter in the Notifications window.</p> + +<p>Because each notification is uniquely identified +by the NotificationManager with an integer ID, you can revise the notification by calling +{@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent) +setLatestEventInfo()} with new values, change some field values of the Notification, and then call +{@link android.app.NotificationManager#notify(int,Notification) notify()} again.</p> + +<p>You can revise each property with the object member fields +(except for the Context and the expanded message title and text). You should always +revise the text message when you update the notification by calling +{@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent) +setLatestEventInfo()} with new values for <var>contentTitle</var> and <var>contentText</var>. +Then call {@link android.app.NotificationManager#notify(int,Notification) notify()} to update the +notification. (Of course, if you've created a <a href="#CustomExpandedView">custom expanded +view</a>, then updating these title and text values has no effect.)</p> + + +<h3 id="Sound">Adding a sound</h3> + +<p>You can alert the user with the default notification sound +(which is defined by the user) or with a sound specified by your application.</p> + +<p>To use the user's default sound, add "DEFAULT_SOUND" to the <var>defaults</var> field:</p> +<pre> +notification.defaults |= Notification.DEFAULT_SOUND; +</pre> + +<p>To use a different sound with your notifications, pass a Uri reference to the +<var>sound</var> field. +The following example uses a known audio file saved to the device SD card:</p> +<pre> +notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); +</pre> + +<p>In the next example, the audio file is chosen from the internal +{@link android.provider.MediaStore.Audio.Media MediaStore}'s {@link android.content.ContentProvider}:</p> +<pre> +notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6"); +</pre> + +<p>In this case, the exact ID of the media file ("6") is known and appended to the content +{@link android.net.Uri}. If you don't know the exact ID, you must query all the +media available in the MediaStore with a {@link android.content.ContentResolver}. +See the <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> +documentation for more information on using a ContentResolver.</p> + +<p>If you want the sound to continuously repeat until the user responds to the notification +or the notification is cancelled, add "FLAG_INSISTENT" to the <var>flags</var> field.</p> + +<p class="note"><strong>Note:</strong> If the <var>defaults</var> field includes +"DEFAULT_SOUND", then the default sound overrides any sound defined by the <var>sound</var> field.</p> + + +<h3 id="Vibration">Adding vibration</h3> + +<p>You can alert the user with the the default +vibration pattern or with a vibration pattern defined by your application.</p> + +<p>To use the default pattern, add "DEFAULT_VIBRATE" to the <var>defaults</var> field:</p> +<pre> +notification.defaults |= Notification.DEFAULT_VIBRATE; +</pre> + +<p>To define your own vibration pattern, pass an array of <em>long</em> values to the +<var>vibrate</var> field:</p> +<pre> +long[] vibrate = {0,100,200,300}; +notification.vibrate = vibrate; +</pre> + +<p>The long array defines the alternating pattern for the length of vibration off and on +(in milliseconds). The first value is how long to wait (off) before beginning, the second +value is the length of the first vibration, the third is the next length off, and so on. +The pattern can be as long as you like, but it can't be set to repeat. +</p> + +<p class="note"><strong>Note:</strong> If the <var>defaults</var> field includes +"DEFAULT_VIBRATE", then the default vibration overrides any vibration defined by the +<var>vibrate</var> field.</p> + + +<h3 id="Lights">Adding flashing lights</h3> + +<p>To alert the user by flashing LED lights, you can implement the default +light pattern (if available), or define your own color and pattern for the lights.</p> + +<p>To use the default light setting, add "DEFAULT_LIGHTS" to the <var>defaults</var> field:</p> +<pre> +notification.defaults |= Notification.DEFAULT_LIGHTS; +</pre> + +<p>To define your own color and pattern, define a value for the <var>ledARGB</var> field +(for the color), the <var>ledOffMS</var> field (length of time, in milliseconds, to +keep the light off), the <var>ledOnMS</var> (length of time, in milliseconds, to keep the light on), +and also add "FLAG_SHOW_LIGHTS" to the <var>flags</var> field:</p> +<pre> +notification.ledARGB = 0xff00ff00; +notification.ledOnMS = 300; +notification.ledOffMS = 1000; +notification.flags |= Notification.FLAG_SHOW_LIGHTS; +</pre> + +<p>In this example, the green light repeatedly flashes on for 300 milliseconds and +turns off for one second. Not every color in the spectrum is supported by the +device LEDs, and not every device supports the same colors, so the hardware +estimates to the best of its ability. Green is the most common notification color.</p> + + +<h3 id="More">More features</h3> + +<p>You can add several more features to your notifications +using Notification fields and flags. Some useful features include the following:</p> + +<dl> + <dt>"FLAG_AUTO_CANCEL" flag</dt> + <dd>Add this to the <var>flags</var> field to automatically cancel the notification + after it is selected from the Notifications window.</dd> + <dt>"FLAG_INSISTENT" flag</dt> + <dd>Add this to the <var>flags</var> field to repeat the audio until the + user responds.</dd> + <dt>"FLAG_ONGOING_EVENT" flag</dt> + <dd>Add this to the <var>flags</var> field to group the notification under the "Ongoing" + title in the Notifications window. This indicates that the application is on-going — + its processes is still running in the background, even when the application is not + visible (such as with music or a phone call).</dd> + <dt>"FLAG_NO_CLEAR" flag</dt> + <dd>Add this to the <var>flags</var> field to indicate that the notification should + <em>not</em> be cleared by the "Clear notifications" button. This is particularly useful if + your notification is on-going.</dd> + <dt><var>number</var> field</dt> + <dd>This value indicates the current number of events represented by the notification. + The appropriate number is overlayed on top of the status bar icon. + If you intend to use this field, then you must start with "1" when the Notification is first + created. (If you change the value from zero to anything greater during an update, the number + is not shown.)</dd> + <dt><var>iconLevel</var> field</dt> + <dd>This value indicates the current level of a + {@link android.graphics.drawable.LevelListDrawable} that is used for the notification icon. + You can animate the icon in the status bar by changing this value to correlate with the + drawable's defined in a LevelListDrawable. See the {@link android.graphics.drawable.LevelListDrawable} + reference for more information.</dd> +</dl> + +<p>See the {@link android.app.Notification} class reference for more information about additional +features that you can customize for your application.</p> + + +<h2 id="CustomExpandedView">Creating a Custom Expanded View</h2> + +<img src="{@docRoot}images/custom_message.png" alt="" style="float:right;" /> + +<p>By default, the expanded view used in the "Notifications" window includes a basic title and text +message. These are defined by the <var>contentTitle</var> and <var>contentText</var> +parameters of the {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent) +setLatestEventInfo()} method. However, you can also define a custom layout for the expanded view using +{@link android.widget.RemoteViews}. The screenshot to the right shows an example of a +custom expanded view that uses an ImageView and TextView in a LinearLayout.</p> + +<p>To define your own layout for the expanded message, +instantiate a {@link android.widget.RemoteViews} object and +pass it to the <var>contentView</var> field of your Notification. Pass the +{@link android.app.PendingIntent} to the <var>contentIntent</var> field.</p> + +<p>Creating a custom expanded view is best understood with an example:</p> + +<ol> + <li>Create the XML layout for the expanded view. + For example, create a layout file called <code>custom_notification_layout.xml</code> and + build it like so: +<pre> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:padding="3dp" + > + <ImageView android:id="@+id/image" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_marginRight="10dp" + /> + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:textColor="#000" + /> +</LinearLayout> +</pre> + + <p>This layout is used for the expanded view, + but the content of the ImageView and TextView still needs to be defined by the applicaiton. + RemoteViews offers some convenient methods that allow you to define this content...</p> + </li> + + <li>In the application code, use the RemoveViews + methods to define the image and text. Then pass the RemoteViews object to the <var>contentView</var> + field of the Notification, as shown in this example: +<pre> +RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout); +contentView.setImageViewResource(R.id.image, R.drawable.notification_image); +contentView.setTextViewText(R.id.text, "Hello, this message is in a custom expanded view"); +notification.contentView = contentView; +</pre> + + <p>As shown here, pass the applicaiton's package name and the layout + resource ID to the RemoteViews constructor. Then, define the content for the ImageView and TextView, + using the {@link android.widget.RemoteViews#setImageViewResource(int, int) setImageViewResource()} + and {@link android.widget.RemoteViews#setTextViewText(int, CharSequence) setTextViewText()}. + In each case, pass the reference ID of the appropriate View object that you want to set, along with + the value for that View. Finally, the RemoteViews object is passed to the Notification in the + <var>contentView</var> field.</p> + </li> + + <li>Because you don't need the + {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent) + setLatestEventInfo()} method when using a custom view, you must define the Intent for the Notification + with the <var>contentIntent</var> field, as in this example: +<pre> +Intent notificationIntent = new Intent(this, MyClass.class); +PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); +notification.contentIntent = contentIntent; +</pre> + </li> + + <li>The notification can now be sent as usual: + <pre>mNotificationManager.notify(CUSTOM_VIEW_ID, notification);</pre> + </li> +</ol> + + +<p>The RemoteViews class also includes methods that you can use to easily add a +{@link android.widget.Chronometer} or {@link android.widget.ProgressBar} +in your notification's expanded view. For more information about creating custom layouts with +RemoteViews, refer to the {@link android.widget.RemoteViews} class reference.</p> + +<p class="warning"><strong>Note:</strong> +When creating a custom expanded view, you must take special care to ensure that your +custom layout functions properly in different device orientations and resolutions. While this +advice applies to all View layouts created on Android, it is especially important in this case +because your layout real estate is very restricted. So don't make your custom layout too +complex and be sure to test it in various configurations.</p> + + + + diff --git a/docs/html/guide/topics/ui/notifiers/toasts.jd b/docs/html/guide/topics/ui/notifiers/toasts.jd new file mode 100644 index 0000000..a800c3c --- /dev/null +++ b/docs/html/guide/topics/ui/notifiers/toasts.jd @@ -0,0 +1,154 @@ +page.title=Creating Toast Notifications +parent.title=Notifying the User +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> + <div id="qv"> + <h2>Key classes</h2> + <ol> + <li>{@link android.widget.Toast}</li> + </ol> + <h2>In this document</h2> + <ol> + <li><a href="#Basics">The Basics</a></li> + <li><a href="#Position">Positioning your Toast</a></li> + <li><a href="#CustomToastView">Creating a Custom Toast View</a></li> + </ol> + </div> +</div> + +<p>A toast notificaiton is a message that pops up on the surface of the window. +It only fills the amount of space required for the message and the user's current +activity remains visible and interactive. The notification automatically fades in and +out, and does not accept interaction events.</p> + +<p>The screenshot below shows an example toast notification from the Alarm application. +Once an alarm is turned on, a toast is displayed to assure you that the +alarm was set.</p> +<img src="{@docRoot}images/toast.png" alt="" /> + +<p>A toast can be created and displayed from an {@link android.app.Activity} or +{@link android.app.Service}. If you create a toast notification from a Service, it +appears in front of the Activity currently in focus.</p> + +<p>If user response to the notification is required, consider using a +<a href="notifications.html">Status Bar Notification</a>.</p> + + +<h2 id="Basics">The Basics</h2> + +<p>First, instantiate a {@link android.widget.Toast} +object with one of the {@link android.widget.Toast#makeText(Context,int,int) makeText()} methods. +This method takes three parameters: the application {@link android.content.Context}, +the text message, and the duration for the toast. It returns a properly initialized Toast +object. You can display the toast notification with {@link android.widget.Toast#show()}, +as shown in the following example:</p> + +<pre> +Context context = getApplicationContext(); +CharSequence text = "Hello toast!"; +int duration = Toast.LENGTH_SHORT; + +Toast toast = Toast.makeText(context, text, duration); +toast.show(); +</pre> + +<p>This example demonstrates everything you need for most toast notifications. +You should rarely need anything else. You may, however, want to position the +toast differently or even use your own layout instead of a simple text message. +The following sections describe how you can do these things.</p> + +<p>You can also chain your methods and avoid holding on to the Toast object, like this:</p> +<pre>Toast.makeText(context, text, duration).show();</pre> + + +<h2 id="Positioning">Positioning your Toast</h2> + +<p>A standard toast notification appears near the bottom of the screen, centered horizontally. +You can change this position with the {@link android.widget.Toast#setGravity(int,int,int)} +method. This accepts three parameters: a {@link android.view.Gravity} constant, +an x-position offset, and a y-position offset.</p> + +<p>For example, if you decide that the toast should appear in the top-left corner, you can set the +gravity like this:</p> +<pre> +toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 0); +</pre> + +<p>If you want to nudge the position to the right, increase the value of the second parameter. +To nudge it down, increase the value of the last parameter. + + +<h2 id="CustomToastView">Creating a Custom Toast View</h2> + +<img src="{@docRoot}images/custom_toast.png" alt="" style="float:right" /> + +<p>If a simple text message isn't enough, you can create a customized layout for your +toast notification. To create a custom layout, define a View layout, +in XML or in your application code, and pass the root {@link android.view.View} object +to the {@link android.widget.Toast#setView(View)} method.</p> + +<p>For example, you can create the layout for the toast visible in the screenshot to the right +with the following XML (saved as <em>toast_layout.xml</em>):</p> +<pre> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/toast_layout_root" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:padding="10dp" + android:background="#DAAA" + > + <ImageView android:id="@+id/image" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_marginRight="10dp" + /> + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:textColor="#FFF" + /> +</LinearLayout> +</pre> + +<p>Notice that the ID of the LinearLayout element is "toast_layout". You must use this +ID to inflate the layout from the XML, as shown here:</p> + +<pre> +LayoutInflater inflater = getLayoutInflater(); +View layout = inflater.inflate(R.layout.toast_layout, + (ViewGroup) findViewById(R.id.toast_layout_root)); + +ImageView image = (ImageView) layout.findViewById(R.id.image); +image.setImageResource(R.drawable.android); +TextView text = (TextView) layout.findViewById(R.id.text); +text.setText("Hello! This is a custom toast!"); + +Toast toast = new Toast(getApplicationContext()); +toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); +toast.setDuration(Toast.LENGTH_LONG); +toast.setView(layout); +toast.show(); +</pre> + +<p>First, retrieve the {@link android.view.LayoutInflater} with +{@link android.app.Activity#getLayoutInflater()} +(or {@link android.content.Context#getSystemService(String) getSystemService()}), +and then inflate the layout from XML using +{@link android.view.LayoutInflater#inflate(int, ViewGroup)}. The first parameter +is the layout resource ID and the second is the root View. You can use +this inflated layout to find more View objects in the layout, so now capture and +define the content for the ImageView and TextView elements. Finally, create +a new Toast with {@link android.widget.Toast#Toast(Context)} and set some properties +of the toast, such as the gravity and duration. Then call +{@link android.widget.Toast#setView(View)} and pass it the inflated layout. +You can now display the toast with your custom layout by calling +{@link android.widget.Toast#show()}.</p> + +<p class="note"><strong>Note:</strong> Do not use the public constructor for a Toast +unless you are going to define the layout with {@link android.widget.Toast#setView(View)}. +If you do not have a custom layout to use, you must use +{@link android.widget.Toast#makeText(Context,int,int)} to create the Toast.</p> + |