diff options
Diffstat (limited to 'docs/html/guide/topics/ui')
-rw-r--r-- | docs/html/guide/topics/ui/binding.jd | 110 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/custom-components.jd | 563 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/declaring-layout.jd | 269 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/how-android-draws.jd | 94 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/index.jd | 235 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/layout-objects.jd | 305 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/menus.jd | 522 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/themes.jd | 173 | ||||
-rw-r--r-- | docs/html/guide/topics/ui/ui-events.jd | 283 |
9 files changed, 2554 insertions, 0 deletions
diff --git a/docs/html/guide/topics/ui/binding.jd b/docs/html/guide/topics/ui/binding.jd new file mode 100644 index 0000000..f9afbc5 --- /dev/null +++ b/docs/html/guide/topics/ui/binding.jd @@ -0,0 +1,110 @@ +page.title=Binding to Data with AdapterView +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="#FillingTheLayout">Filling the Layout with Data</a></li> + <li><a href="#HandlingUserSelections">Handling User Selections</a></li> + </ol> + + <h2>See also</h2> + <ol> + <li><a href="{@docRoot}guide/tutorials/views/hello-spinner.html">Hello Spinner tutorial</a></li> + <li><a href="{@docRoot}guide/tutorials/views/hello-listview.html">Hello ListView tutorial</a></li> + <li><a href="{@docRoot}guide/tutorials/views/hello-gridview.html">Hello GridView tutorial</a></li> + </ol> +</div> +</div> + +<p>The {@link android.widget.AdapterView} is a ViewGroup subclass whose child Views are determined by an {@link android.widget.Adapter Adapter} that +binds to data of some type. AdapterView is useful whenever you need to display stored data (as opposed to resource strings or drawables) in your layout.</p> + +<p>{@link android.widget.Gallery Gallery}, {@link android.widget.ListView ListView}, and {@link android.widget.Spinner Spinner} are examples of AdapterView subclasses that you can use to bind to a specific type of data and display it in a certain way. </p> + + +<p>AdapterView objects have two main responsibilities: </p> +<ul> + <li>Filling the layout with data + </li> + <li>Handling user selections + </li> +</ul> + + +<h2 id="FillingTheLayout">Filling the Layout with Data</h2> +<p>Inserting data into the layout is typically done by binding the AdapterView class to an {@link +android.widget.Adapter}, which retireves data from an external source (perhaps a list that +the code supplies or query results from the device's database). </p> +<p>The following code sample does the following:</p> +<ol> + <li>Creates a {@link android.widget.Spinner Spinner} with an existing View and binds it to a new ArrayAdapter +that reads an array of colors from the local resources.</li> + <li>Creates another Spinner object from a View and binds it to a new SimpleCursorAdapter that will read +people's names from the device contacts (see {@link android.provider.Contacts.People}).</li> +</ol> + +<pre> +// Get a Spinner and bind it to an ArrayAdapter that +// references a String array. +Spinner s1 = (Spinner) findViewById(R.id.spinner1); +ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( + this, R.array.colors, android.R.layout.simple_spinner_item); +adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); +s1.setAdapter(adapter); + +// Load a Spinner and bind it to a data query. +private static String[] PROJECTION = new String[] { + People._ID, People.NAME + }; + +Spinner s2 = (Spinner) findViewById(R.id.spinner2); +Cursor cur = managedQuery(People.CONTENT_URI, PROJECTION, null, null); + +SimpleCursorAdapter adapter2 = new SimpleCursorAdapter(this, + android.R.layout.simple_spinner_item, // Use a template + // that displays a + // text view + cur, // Give the cursor to the list adatper + new String[] {People.NAME}, // Map the NAME column in the + // people database to... + new int[] {android.R.id.text1}); // The "text1" view defined in + // the XML template + +adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); +s2.setAdapter(adapter2); +</pre> + +<p>Note that it is necessary to have the People._ID column in projection used with CursorAdapter +or else you will get an exception.</p> + + +<h2 id="HandlingUserSelections">Handling User Selections</h2> +<p>You handle the user's selecction by setting the class's {@link +android.widget.AdapterView.OnItemClickListener} member to a listener and +catching the selection changes. </p> +<pre> +// Create a message handling object as an anonymous class. +private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() { + public void onItemClick(AdapterView parent, View v, int position, long id) + { + // Display a messagebox. + Toast.makeText(mContext,"You've got an event",Toast.LENGTH_SHORT).show(); + } +}; + +// Now hook into our object and set its onItemClickListener member +// to our class handler object. +mHistoryView = (ListView)findViewById(R.id.history); +mHistoryView.setOnItemClickListener(mMessageClickedHandler); +</pre> + +<div class="special"> +<p>For more discussion on how to create different AdapterViews, read the following tutorials: +<a href="{@docRoot}guide/tutorials/views/hello-spinner.html">Hello Spinner</a>, +<a href="{@docRoot}guide/tutorials/views/hello-listview.html">Hello ListView</a>, and +<a href="{@docRoot}guide/tutorials/views/hello-gridview.html">Hello GridView</a>. +</div> diff --git a/docs/html/guide/topics/ui/custom-components.jd b/docs/html/guide/topics/ui/custom-components.jd new file mode 100644 index 0000000..eccc2ca --- /dev/null +++ b/docs/html/guide/topics/ui/custom-components.jd @@ -0,0 +1,563 @@ +page.title=Building Custom Components +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="#basic">The Basic Approach</a></li> + <li><a href="#custom">Fully Customized Components</a></li> + <li><a href="#compound">Compound Controls</a></li> + <li><a href="#modifying">Modifying an Existing View Type</a></li> + </ol> +</div> +</div> + +<p>Android offers a sophisticated and powerful componentized model for building your UI, +based on the fundamental layout classes: {@link android.view.View} and +{@link android.view.ViewGroup}. To start with, the platform includes a variety of prebuilt +View and ViewGroup subclasses — called widgets and layouts, respectively — +that you can use to construct your UI.</p> + +<p>A partial list of available widgets includes {@link android.widget.Button Button}, +{@link android.widget.TextView TextView}, +{@link android.widget.EditText EditText}, +{@link android.widget.ListView ListView}, +{@link android.widget.CheckBox CheckBox}, +{@link android.widget.RadioButton RadioButton}, +{@link android.widget.Gallery Gallery}, +{@link android.widget.Spinner Spinner}, and the more special-purpose +{@link android.widget.AutoCompleteTextView AutoCompleteTextView}, +{@link android.widget.ImageSwitcher ImageSwitcher}, and +{@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}, +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 +the widget or layout and override its methods. +</p> + +<p>Creating your own View subclasses gives you precise control over the appearance and function +of a screen element. To give an idea of the control you get with custom views, here are some +examples of what you could do with them:</p> + +<ul> + <li> + You could create a completely custom-rendered View type, for example a "volume + control" knob rendered using 2D graphics, and which resembles an + analog electronic control. + </li> + <li> + You could combine a group of View components into a new single component, perhaps + to make something like a ComboBox (a combination of popup list and free + entry text field), a dual-pane selector control (a left and right pane + with a list in each where you can re-assign which item is in which + list), and so on. + </li> + <li> + You could override the way that an EditText component is rendered on the screen + (the <a href="{@docRoot}guide/samples/NotePad/index.html">Notepad Tutorial</a> uses this to good effect, + to create a lined-notepad page). + </li> + <li> + You could capture other events like key presses and handle them in some custom + way (such as for a game). + </li> +</ul> +<p> +The sections below explain how to create custom Views and use them in your application. +For detailed reference information, see the {@link android.view.View} class. </p> + + +<h2 id="basic">The Basic Approach</h2> + +<p>Here is a high level overview of what you need to know to get started in creating your own +View components:</p> + +<ol> + <li> + Extend an existing {@link android.view.View View} class or subclass + with your own class. + </li> + <li> + Override some of the methods from the superclass. The superclass methods + to override start with '<code>on</code>', for + example, {@link android.view.View#onDraw onDraw()}, + {@link android.view.View#onMeasure onMeasure()}, and + {@link android.view.View#onKeyDown onKeyDown()}. + This is similar to the <code>on...</code> events in {@link android.app.Activity Activity} + or {@link android.app.ListActivity ListActivity} + that you override for lifecycle and other functionality hooks. + <li> + Use your new extension class. Once completed, your new extension class + can be used in place of the view upon which it was based. + </li> +</ol> +<p class="note"><strong>Tip:</strong> + Extension classes can be defined as inner classes inside the activities + that use them. This is useful because it controls access to them but + isn't necessary (perhaps you want to create a new public View for + wider use in your application). +</p> + + + +<h2 id="custom">Fully Customized Components</h2> +<p> +Fully customized components can be used to create graphical components that +appear however you wish. Perhaps a graphical VU +meter that looks like an old analog gauge, or a sing-a-long text view where +a bouncing ball moves along the words so you can sing along with a karaoke +machine. Either way, you want something that the built-in components just +won't do, no matter how you combine them.</p> +<p>Fortunately, you can easily create components that look and behave in any +way you like, limited perhaps only by your imagination, the size of the +screen, and the available processing power (remember that ultimately your +application might have to run on something with significantly less power +than your desktop workstation).</p> +<p>To create a fully customized component:</p> +<ol> + <li> + The most generic view you can extend is, unsurprisingly, {@link + android.view.View View}, so you will usually start by extending this to + create your new super component. + </li> + <li> + You can supply a constructor which can + take attributes and parameters from the XML, and you can also consume + your own such attributes and parameters (perhaps the color and range of + the VU meter, or the width and damping of the needle, etc.) + </li> + <li> + You will probably want to create your own event listeners, + property accessors and modifiers, and possibly more sophisticated + behavior in your component class as well. + </li> + <li> + You will almost certainly want to override <code>onMeasure()</code> and + are also likely to need to override <code>onDraw()</code> if you want + the component to show something. While both have default behavior, + the default <code>onDraw()</code> will do nothing, and the default + <code>onMeasure()</code> will always set a size of 100x100 — which is + probably not what you want. + </li> + <li> + Other <code>on...</code> methods may also be overridden as required. + </li> +</ol> + +<h3>Extend <code>onDraw()</code> and <code>onMeasure()</code></h3> +<p>The <code>onDraw()</code> method delivers you a {@link android.graphics.Canvas Canvas} +upon which you can implement anything you want: 2D graphics, other standard or +custom components, styled text, or anything else you can think of.</p> + +<p class="note"><strong>Note:</strong> +This does not apply to 3D graphics. If you want to +use 3D graphics, you must extend {@link android.view.SurfaceView SurfaceView} +instead of View, and draw from a seperate thread. See the +GLSurfaceViewActivity sample +for details.</p> + +<p><code>onMeasure()</code> is a little more involved. <code>onMeasure()</code> +is a critical piece of the rendering contract between your component and its +container. <code>onMeasure()</code> should be overridden to efficiently and +accurately report the measurements of its contained parts. This is made +slightly more complex by the requirements of limits from the parent +(which are passed in to the <code>onMeasure()</code> method) and by the +requirement to call the <code>setMeasuredDimension()</code> method with the +measured width and height once they have been calculated. If you fail to +call this method from an overridden <code>onMeasure()</code> method, the +result will be an exception at measurement time.</p> +<p>At a high level, implementing <code>onMeasure()</code> looks something + like this:</p> + +<ol> + <li> + The overridden <code>onMeasure()</code> method is called with width and + height measure specifications (<code>widthMeasureSpec</code> and + <code>heightMeasureSpec</code> parameters, both are integer codes + representing dimensions) which should be treated as requirements for + the restrictions on the width and height measurements you should produce. A + full reference to the kind of restrictions these specifications can require + can be found in the reference documentation under {@link + android.view.View#onMeasure View.onMeasure(int, int)} (this reference + documentation does a pretty good job of explaining the whole measurement + operation as well). + </li> + <li> + Your component's <code>onMeasure()</code> method should calculate a + measurement width and height which will be required to render the + component. It should try to stay within the specifications passed in, + although it can choose to exceed them (in this case, the parent can + choose what to do, including clipping, scrolling, throwing an exception, + or asking the <code>onMeasure()</code> to try again, perhaps with + different measurement specifications). + </li> + <li> + Once the width and height are calculated, the <code>setMeasuredDimension(int + width, int height)</code> method must be called with the calculated + measurements. Failure to do this will result in an exception being + thrown. + </li> +</ol> + +<p> +Here's a summary of some of the other standard methods that the framework calls on views: +</p> +<table border="2" width="85%" align="center" cellpadding="5"> + <thead> + <tr><th>Category</th> <th>Methods</th> <th>Description</th></tr> + </thead> + + <tbody> + <tr> + <td rowspan="2">Creation</td> + <td>Constructors</td> + <td>There is a form of the constructor that are called when the view + is created from code and a form that is called when the view is + inflated from a layout file. The second form should parse and apply + any attributes defined in the layout file. + </td> + </tr> + <tr> + <td><code>{@link android.view.View#onFinishInflate()}</code></td> + <td>Called after a view and all of its children has been inflated + from XML.</td> + </tr> + + <tr> + <td rowspan="3">Layout</td> + <td><code>{@link android.view.View#onMeasure}</code></td> + <td>Called to determine the size requirements for this view and all + of its children. + </td> + </tr> + <tr> + <td><code>{@link android.view.View#onLayout}</code></td> + <td>Called when this view should assign a size and position to all + of its children. + </td> + </tr> + <tr> + <td><code>{@link android.view.View#onSizeChanged}</code></td> + <td>Called when the size of this view has changed. + </td> + </tr> + + <tr> + <td>Drawing</td> + <td><code>{@link android.view.View#onDraw}</code></td> + <td>Called when the view should render its content. + </td> + </tr> + + <tr> + <td rowspan="4">Event processing</td> + <td><code>{@link android.view.View#onKeyDown}</code></td> + <td>Called when a new key event occurs. + </td> + </tr> + <tr> + <td><code>{@link android.view.View#onKeyUp}</code></td> + <td>Called when a key up event occurs. + </td> + </tr> + <tr> + <td><code>{@link android.view.View#onTrackballEvent}</code></td> + <td>Called when a trackball motion event occurs. + </td> + </tr> + <tr> + <td><code>{@link android.view.View#onTouchEvent}</code></td> + <td>Called when a touch screen motion event occurs. + </td> + </tr> + + <tr> + <td rowspan="2">Focus</td> + <td><code>{@link android.view.View#onFocusChanged}</code></td> + <td>Called when the view gains or loses focus. + </td> + </tr> + + <tr> + <td><code>{@link android.view.View#onWindowFocusChanged}</code></td> + <td>Called when the window containing the view gains or loses focus. + </td> + </tr> + + <tr> + <td rowspan="3">Attaching</td> + <td><code>{@link android.view.View#onAttachedToWindow()}</code></td> + <td>Called when the view is attached to a window. + </td> + </tr> + + <tr> + <td><code>{@link android.view.View#onDetachedFromWindow}</code></td> + <td>Called when the view is detached from its window. + </td> + </tr> + + <tr> + <td><code>{@link android.view.View#onWindowVisibilityChanged}</code></td> + <td>Called when the visibility of the window containing the view + has changed. + </td> + </tr> + </tbody> + + </table> + + + +<h3 id="customexample">A Custom View Example</h3> +<p>The CustomView sample in the +<a href="{@docRoot}guide/samples/ApiDemos/index.html">API Demos</a> provides an example +of a customized View. The custom View is defined in the +<a href="{@docRoot}guide/samples/ApiDemos/src/com/example/android/apis/view/LabelView.html">LabelView</a> +class.</p> +<p>The LabelView sample demonstrates a number of different aspects of custom components:</p> +<ul> + <li>Extending the View class for a completely custom component.</li> + <li>Parameterized constructor that takes the view inflation parameters + (parameters defined in the XML). Some of these are passed through to the + View superclass, but more importantly, there are some custom attributes defined + and used for LabelView.</li> + <li>Standard public methods of the type you would expect to see for a label + component, for example <code>setText()</code>, <code>setTextSize()</code>, + <code>setTextColor()</code> and so on.</li> + <li>An overridden <code>onMeasure</code> method to determine and set the + rendering size of the component. (Note that in LabelView, the real work is done + by a private <code>measureWidth()</code> method.)</li> + <li>An overridden <code>onDraw()</code> method to draw the label onto the + provided canvas.</li> +</ul> +<p>You can see some sample usages of the LabelView custom View in +<a href="{@docRoot}guide/samples/ApiDemos/res/layout/custom_view_1.html">custom_view_1.xml</a> +from the samples. In particular, you can see a mix of both <code>android:</code> +namespace parameters and custom <code>app:</code> namespace parameters. These +<code>app:</code> parameters are the custom ones that the LabelView recognizes +and works with, and are defined in a styleable inner class inside of the +samples R resources definition class.</p> + + +<h2 id="compound">Compound Controls +</h2> +<p>If you don't want to create a completely customized component, but instead +are looking to put together a reusable component that consists of a group of +existing controls, then creating a Compound Component (or Compound Control) might +fit the bill. In a nutshell, this brings together a number of more atomic +controls (or views) into a logical group of items that can be treated as a +single thing. For example, a Combo Box can be thought of as a +combination of a single line EditText field and an adjacent button with an attached + PopupList. If you press the button and select +something from the list, it populates the EditText field, but the user can +also type something directly into the EditText if they prefer.</p> +<p>In Android, there are actually two other Views readily available to do +this: {@link android.widget.Spinner Spinner} and +{@link android.widget.AutoCompleteTextView AutoCompleteTextView}, but +regardless, the concept of a Combo Box makes an easy-to-understand +example.</p> +<p>To create a compound component:</p> +<ol> + <li> + The usual starting point is a Layout of some kind, so create a class + that extends a Layout. Perhaps in the case of a Combo box we might use + a LinearLayout with horizontal orientation. Remember that other layouts + can be nested inside, so the compound component can be arbitrarily + complex and structured. Note that just like with an Activity, you can + use either the declarative (XML-based) approach to creating the + contained components, or you can nest them programmatically from your + code. + </li> + <li> + In the constructor for the new class, take whatever parameters the + superclass expects, and pass them through to the superclass constructor + first. Then you can set up the other views to use within your new + component; this is where you would create the EditText field and the + PopupList. Note that you also might introduce your own attributes and + parameters into the XML that can be pulled out and used by your + constructor. + </li> + <li> + You can also create listeners for events that your contained views might + generate, for example, a listener method for the List Item Click Listener + to update the contents of the EditText if a list selection is made. + </li> + <li> + You might also create your own properties with accessors and modifiers, + for example, allow the EditText value to be set initially in the + component and query for its contents when needed. + </li> + <li> + In the case of extending a Layout, you don't need to override the + <code>onDraw()</code> and <code>onMeasure()</code> methods since the + layout will have default behavior that will likely work just fine. However, + you can still override them if you need to. + </li> + <li> + You might override other <code>on...</code> methods, like + <code>onKeyDown()</code>, to perhaps choose certain default values from + the popup list of a combo box when a certain key is pressed. + </li> +</ol> +<p> + To summarize, the use of a Layout as the basis for a Custom Control has a +number of advantages, including:</p> + +<ul> + <li> + You can specify the layout using the declarative XML files just like + with an activity screen, or you can create views programmatically and + nest them into the layout from your code. + </li> + <li> + The <code>onDraw()</code> and <code>onMeasure()</code> methods (plus + most of the other <code>on...</code> methods) will likely have suitable behavior so + you don't have to override them. + </li> + <li> + In the end, you can very quickly construct arbitrarily complex compound + views and re-use them as if they were a single component. + </li> +</ul> +<h4>Examples of Compound Controls</h4> +<p>In the API Demos project + that comes with the SDK, there are two List + examples — Example 4 and Example 6 under Views/Lists demonstrate a + SpeechView which extends LinearLayout to make a component for displaying + Speech quotes. The corresponding classes in the sample code are + <code>List4.java</code> and <code>List6.java</code>.</p> + + + +<h2 id="modifying">Modifying an Existing View Type</h2> +<p>There is an even easier option for creating a custom View which is +useful in certain circumstances. If there is a component that is already very +similar to what you want, you can simply extend that component and just +override the behavior that you want to change. You can do all of the things +you would do with a fully customized component, but by starting with a more +specialized class in the View heirarchy, you can also get a lot of behavior for +free that probably does exactly what you want.</p> +<p>For example, the SDK includes a <a +href="{@docRoot}guide/samples/NotePad/index.html">NotePad application</a> in the +samples. This demonstrates many aspects of using the Android platform, among +them is extending an EditText View to make a lined notepad. This is not a +perfect example, and the APIs for doing this might change from this early +preview, but it does demonstrate the principles.</p> +<p>If you haven't done so already, import the +NotePad sample into Eclipse (or +just look at the source using the link provided). In particular look at the definition of +<code>MyEditText</code> in the <a +href="{@docRoot}guide/samples/NotePad/src/com/example/android/notepad/NoteEditor.html">NoteEditor.java</a> +file.</p> +<p>Some points to note here</p> +<ol> + <li> + <strong>The Definition</strong> + <p>The class is defined with the following line:<br/> + <code>public static class MyEditText extends EditText</code></p> + + <ul> + <li> + It is defined as an inner class within the <code>NoteEditor</code> + activity, but it is public so that it could be accessed as + <code>NoteEditor.MyEditText</code> from outside of the <code>NoteEditor</code> + class if desired. + </li> + <li> + It is <code>static</code>, meaning it does not generate the so-called + "synthetic methods" that allow it to access data from the parent + class, which in turn means that it really behaves as a separate + class rather than something strongly related to <code>NoteEditor</code>. + This is a cleaner way to create inner classes if they do not need + access to state from the outer class, keeps the generated class + small, and allows it to be used easily from other classes. + </li> + <li> + It extends <code>EditText</code>, which is the View we have chosen to + customize in this case. When we are finished, the new class will be + able to substitute for a normal <code>EditText</code> view. + </li> + </ul> + </li> + <li> + <strong>Class Initialization</strong> + <p>As always, the super is called first. Furthermore, + this is not a default constructor, but a parameterized one. The + EditText is created with these parameters when it is inflated from an + XML layout file, thus, our constructor needs to both take them and pass them + to the superclass constructor as well.</p> + </li> + <li> + <strong>Overridden Methods</strong> + <p>In this example, there is only one method to be overridden: + <code>onDraw()</code> — but there could easily be others needed when you + create your own custom components.</p> + <p>For the NotePad sample, overriding the <code>onDraw()</code> method allows + us to paint the blue lines on the <code>EditText</code> view canvas (the + canvas is passed into the overridden <code>onDraw()</code> method). The + super.onDraw() method is called before the method ends. The + superclass method should be invoked, but in this case, we do it at the + end after we have painted the lines we want to include.</p> + <li> + <strong>Use the Custom Component</strong> + <p>We now have our custom component, but how can we use it? In the + NotePad example, the custom component is used directly from the + declarative layout, so take a look at <code>note_editor.xml</code> in the + <code>res/layout</code> folder.</p> +<pre> +<view + class="com.android.notepad.NoteEditor$MyEditText" + id="@+id/note" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:background="@android:drawable/empty" + android:padding="10dip" + android:scrollbars="vertical" + android:fadingEdge="vertical" /> +</pre> + + <ul> + <li> + The custom component is created as a generic view in the XML, and + the class is specified using the full package. Note also that the + inner class we defined is referenced using the + <code>NoteEditor$MyEditText</code> notation which is a standard way to + refer to inner classes in the Java programming language. + <p>If your custom View component is not defined as an inner class, then you can, + alternatively, declare the View component + with the XML element name, and exclude the <code>class</code> attribute. For example:</p> +<pre> +<com.android.notepad.MyEditText + id="@+id/note" + ... /> +</pre> + <p>Notice that the <code>MyEditText</code> class is now a separate class file. When the class + is nested in the <code>NoteEditor</code> class, this technique will not work.</p> + </li> + <li> + The other attributes and parameters in the definition are the ones + passed into the custom component constructor, and then passed + through to the EditText constructor, so they are the same + parameters that you would use for an EditText view. Note that it is + possible to add your own parameters as well, and we will touch on + this again below. + </li> + </ul> + </li> +</ol> +<p>And that's all there is to it. Admittedly this is a simple case, but +that's the point — creating custom components is only as complicated as you +need it to be.</p> +<p>A more sophisticated component may override even more <code>on...</code> methods and +introduce some of its own helper methods, substantially customizing its properties and +behavior. The only limit is your imagination and what you need the component to +do.</p> + 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/ui/layout-objects.jd b/docs/html/guide/topics/ui/layout-objects.jd new file mode 100644 index 0000000..cf85fd6 --- /dev/null +++ b/docs/html/guide/topics/ui/layout-objects.jd @@ -0,0 +1,305 @@ +page.title=Common Layout Objects +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="#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> +</div> +</div> + +<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 +object. It's basically a blank space on your screen that you can +later fill with a single object — for example, a picture that you'll swap in and out. +All child elements of the FrameLayout are pinned to the top left corner of the screen; you cannot +specify a different location for a child view. Subsequent child views will simply be drawn over previous ones, +partially or totally obscuring them (unless the newer object is transparent). +</p> + + +<h2 id="linearlayout">LinearLayout</h2> +<p>{@link android.widget.LinearLayout LinearLayout} aligns all children in a +single direction — vertically or horizontally, depending on how you +define the <code>orientation</code> attribute. All children are +stacked one after the other, so a vertical list will only have one child per +row, no matter how wide they are, and a horizontal list will only be one row +high (the height of the tallest child, plus padding). A {@link +android.widget.LinearLayout LinearLayout} respects <em>margin</em>s between children +and the <em>gravity</em> (right, center, or left alignment) of each child. </p> + +<p>{@link android.widget.LinearLayout LinearLayout} also supports assigning a +<em>weight</em> to individual children. This attribute assigns an "importance" value to a view, +and allows it to expand to fill any remaining space in the parent view. +Child views can specify an integer weight value, and then any remaining space in the view group is +assigned to children in the proportion of their declared weight. Default +weight is zero. For example, if there are three text boxes and two of +them declare a weight of 1, while the other is given no weight (0), the third text box without weight +will not grow and will only occupy the area required by its content. +The other two will expand equally to fill the space remaining after all three boxes are measured. +If the third box is then given a weight of 2 (instead of 0), then it is now declared +"more important" than both the others, so it gets half the total remaining space, while the first two +share the rest equally.</p> + +<div class="sidebox"> +<p><strong>Tip</strong>: To create a proportionate size +layout on the screen, create a container view group object with the +<code>layout_width</code> and <code>layout_height</code> attributes set to <var>fill_parent</var>; assign +the children <code>height</code> or <code>width</code> to <code>0</code> (zero); then assign relative +<code>weight</code> values +to each child, depending on what proportion of the screen each should +have.</p> +</div> + +<p>The following two forms represent a {@link android.widget.LinearLayout LinearLayout} with a set of elements: a +button, some labels and text boxes. The text boxes have their width set to <var>fill_parent</var>; other +elements are set to <var>wrap_content</var>. The gravity, by default, is left. +The difference between the two versions of the form is that the form +on the left has weight values unset (0 by default), while the form on the right has +the comments text box weight set to 1. If the Name textbox had also been set +to 1, the Name and Comments text boxes would be the same height. </p> + +<img src="{@docRoot}images/linearlayout.png" alt="" /> + +<p>Within a horizontal {@link android.widget.LinearLayout LinearLayout}, items are aligned by the position of +their text base line (the first line of the first list element — topmost or +leftmost — is considered the reference line). This is so that people scanning +elements in a form shouldn't have to jump up and down to read element text in +neighboring elements. This can be turned off by setting +<code>android:baselineAligned="false"</code> in the layout XML. </p> + +<p>To view other sample code, see the +<a href="{@docRoot}guide/tutorials/views/hello-linearlayout.html">Hello LinearLayout</a> tutorial.</p> + + +<h2 id="tablelayout">TableLayout</h2> +<p>{@link android.widget.TableLayout} positions its children into rows + and columns. TableLayout containers do not display border lines for their rows, columns, + or cells. The table will have as many columns as the row with the most cells. A table can leave +cells empty, but cells cannot span columns, as they can in HTML.</p> +<p>{@link android.widget.TableRow} objects are the child views of a TableLayout +(each TableRow defines a single row in the table). +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 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> + +<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 + fits the screen. See the {@link android.widget.TableLayout TableLayout reference} +documentation for more details. </p> + +<p>To view sample code, see the <a href="{@docRoot}guide/tutorials/views/hello-tablelayout.html">Hello +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 + align two elements by right border, or make one below another, centered in + the screen, centered left, and so on. Elements are rendered in the order given, so if the first element + is centered in the screen, other elements aligning themselves to that element + 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>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> + + +<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>, + <code>below</code>, <code>alignTop</code>, <code>toLeft</code>, <code>padding[Bottom|Left|Right|Top]</code>, + and <code>margin[Bottom|Left|Right|Top]</code>. Note that some of these parameters specifically support + relative layout positions — their values must be the ID of the element to which you'd like this view laid relative. + For example, assigning the parameter <code>toLeft="my_button"</code> to a TextView would place the TextView to + the left of the View with the ID <var>my_button</var> (which must be written in the XML <em>before</em> the TextView). </p> + +<p>To view this sample code, see the <a href="{@docRoot}guide/tutorials/views/hello-relativelayout.html">Hello +RelativeLayout</a> tutorial.</p> + + +<h2 id="viewgroupsummary">Summary of Important View Groups</h2> +<p>These objects all hold child UI elements. Some provide their own form of a visible UI, while others + are invisible structures that only manage the layout of their child views. </p> +<table width="100%" border="1"> + <tr> + <th scope="col">Class</th> + <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> + </tr> + <tr> + <td>{@link android.widget.Gallery Gallery} </td> + <td>A horizontal scrolling display of images, from a bound list. </td> + </tr> + <tr> + <td>{@link android.widget.GridView GridView} </td> + <td>Displays a scrolling grid of m columns and n rows.</td> + </tr> + <tr> + <td>{@link android.widget.LinearLayout LinearLayout} </td> + <td>A layout that organizes its children into a single horizontal or vertical + row. It creates a scrollbar if the length of the window exceeds the length + of the screen. </td> + </tr> + <tr> + <td>{@link android.widget.ListView ListView} </td> + <td>Displays a scrolling single column list. </td> + </tr> + <tr> + <td>{@link android.widget.RelativeLayout RelativeLayout} </td> + <td>Enables you to specify the location of child objects relative to each + other (child A to the left of child B) or to the parent (aligned to the + top of the parent). </td> + </tr> + <tr> + <td>{@link android.widget.ScrollView ScrollView} </td> + <td>A vertically scrolling column of elements. </td> + </tr> + <tr> + <td>{@link android.widget.Spinner Spinner} </td> + <td>Displays a single item at a time from a bound list, inside a one-row + textbox. Rather like a one-row listbox that can scroll either horizontally + or vertically. </td> + </tr> + <tr> + <td>{@link android.view.SurfaceView SurfaceView} </td> + <td>Provides direct access to a dedicated drawing surface. It can hold child + views layered on top of the surface, but is intended for applications + that need to draw pixels, rather than using widgets. </td> + </tr> + <tr> + <td>{@link android.widget.TabHost TabHost} </td> + <td>Provides a tab selection list that monitors clicks and enables the application + to change the screen whenever a tab is clicked. </td> + </tr> + <tr> + <td>{@link android.widget.TableLayout TableLayout} </td> + <td>A tabular layout with an arbitrary number of rows and columns, each cell + holding the widget of your choice. The rows resize to fit the largest + column. The cell borders are not + visible. </td> + </tr> + <tr> + <td>{@link android.widget.ViewFlipper ViewFlipper} </td> + <td>A list that displays one item at a time, inside a one-row textbox. It + can be set to swap items at timed intervals, like a slide show. </td> + </tr> + <tr> + <td>{@link android.widget.ViewSwitcher ViewSwitcher} </td> + <td>Same as ViewFlipper. </td> + </tr> +</table> diff --git a/docs/html/guide/topics/ui/menus.jd b/docs/html/guide/topics/ui/menus.jd new file mode 100644 index 0000000..ed796ee --- /dev/null +++ b/docs/html/guide/topics/ui/menus.jd @@ -0,0 +1,522 @@ +page.title=Creating Menus +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="#options-menu">Options Menu</a></li> + <li><a href="#context-menu">Context 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> + <li><a href="#groups">Menu groups</a></li> + <li><a href="#checkable">Checkable menu items</a></li> + <li><a href="#shortcuts">Shortcut keys</a></li> + <li><a href="#intents">Menu item intents</a></li> + </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> + +<p>Menus are an important part of any application. They provide familiar interfaces +that reveal application functions and settings. Android offers an easy programming interface +for developers to provide standardized application menus for various situations.</p> + +<p>Android offers three fundamental types of application menus:</p> +<dl> + <dt><strong>Options Menu</strong></dt> + <dd>This is the primary set of menu items for an Activity. It is revealed by pressing + the device MENU key. Within the Options Menu are two groups of menu items: + <dl style="margin-top:1em"> + <dt><em>Icon Menu</em></dt> + <dd>This is the collection of items initially visible at the bottom of the screen + at the press of the MENU key. It supports a maximum of six menu items. + These are the only menu items that support icons and the only menu items that <em>do not</em> support + checkboxes or radio buttons.</dd> + <dt><em>Expanded Menu</em></dt> + <dd>This is a vertical list of items exposed by the "More" menu item from the Icon Menu. + It exists only when the Icon Menu becomes over-loaded and is comprised of the sixth + Option Menu item and the rest.</dd> + </dl> + </dd> + <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>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 Submenu item cannot support nested Submenus. </dd> +</dl> + + +<h2 id="options-menu">Options Menu</h2> +<img align="right" src="{@docRoot}images/options_menu.png" /> +<p>The Options Menu is opened by pressing the device MENU key. +When opened, the Icon Menu is displayed, which holds the first six menu items. +If more than six items are added to the Options Menu, then those that can't fit +in the Icon Menu are revealed in the Expanded Menu, via the "More" menu item. The Expanded Menu +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="#submenu">Submenus</a> for organizing topics +and including extra menu functionality.</p> + +<p>When this menu is opened for the first time, +the Android system will call the Activity <code>{@link android.app.Activity#onCreateOptionsMenu(Menu) +onCreateOptionsMenu()}</code> callback method. Override this method in your Activity +and populate the {@link android.view.Menu} object given to you. You can populate the menu by +inflating a menu resource that was <a href="#xml">defined in XML</a>, or by calling +<code>{@link android.view.Menu#add(CharSequence) add()}</code> +for each item you'd like in the menu. This method adds a {@link android.view.MenuItem}, and returns the +newly created object to you. You can use the returned MenuItem to set additional properties like +an icon, a keyboard shortcut, an intent, and other settings for the item.</p> + +<p>There are multiple <code>{@link android.view.Menu#add(CharSequence) add()}</code> methods. +Usually, you'll want to use one that accepts an <var>itemId</var> argument. +This is a unique integer that allows you to identify the item during a callback.</p> + +<p>When a menu item is selected from the Options Menu, you will recieve a callback to the +<code>{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}</code> +method of your Activity. This callback passes you the +<code>MenuItem</code> that has been selected. You can identify the item by requesting the +<var>itemId</var>, with <code>{@link android.view.MenuItem#getItemId() getItemId()}</code>, +which returns the integer that was assigned with the <code>add()</code> method. Once you identify +the menu item, you can take the appropriate action.</p> + +<p>Here's an example of this procedure, inside an Activity, wherein we create an +Options Menu and handle item selections:</p> + +<pre> +/* Creates the menu items */ +public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, MENU_NEW_GAME, 0, "New Game"); + menu.add(0, MENU_QUIT, 0, "Quit"); + return true; +} + +/* Handles item selections */ +public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case MENU_NEW_GAME: + newGame(); + return true; + case MENU_QUIT: + quit(); + return true; + } + return false; +} +</pre> + +<p>The <code>add()</code> method used in this sample takes four arguments: +<var>groupId</var>, <var>itemId</var>, <var>order</var>, and <var>title</var>. +The <var>groupId</var> allows you to associate this menu item with a group of other items +(more about <a href="#groups">Menu groups</a>, below) — in +this example, we ignore it. <var>itemId</var> is a unique integer that we give the +MenuItem so that can identify it in the next callback. <var>order</var> allows us to +define the display order of the item — by default, they are displayed by the +order in which we add them. <var>title</var> is, of course, the name that goes on the +menu item (this can also be a +<a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">string resource</a>, +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="#submenu">Submenu</a>.</p> + +<h3>Adding icons</h3> +<p>Icons can also be added to items that appears in the Icon Menu with +<code>{@link android.view.MenuItem#setIcon(Drawable) setIcon()}</code>. For example:</p> +<pre> +menu.add(0, MENU_QUIT, 0, "Quit") + .setIcon(R.drawable.menu_quit_icon);</pre> + +<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 +menu options depending on the current state of an application or game.</p> + +<p class="note"><strong>Note:</strong> +When changing items in the menu, it's bad practice to do so based on the currently selected item. +Keep in mind that, when in touch mode, there will not be a selected (or focused) item. Instead, you +should use a <a href="#context-menu">Context Menu</a> for such behaviors, when you want to provide +functionality based on a particular item in the UI.</p> + + +<h2 id="context-menu">Context Menu</h2> +<p>The Android context menu is similar, in concept, to the menu revealed with a "right-click" on a PC. +When a view is registered to a context menu, +performing a "long-press" (press and hold for about two seconds) on the object +will reveal a floating menu that provides functions relating to that item. +Context menus can be registered to any View object, +however, they are most often used for items in a +{@link android.widget.ListView}, which helpfully indicates the presence of the context menu +by transforming the background color of the ListView item when pressed. +(The items in the phone's contact list offer an example of this feature.) +</p> + +<p class="note"><strong>Note:</strong> Context menu items do not support icons or shortcut keys.</p> + +<p>To create a context menu, you must override the Activity's context menu callback methods: +<code>{@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) onCreateContextMenu()}</code> and +<code>{@link android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}</code>. +Inside the <code>onCreateContextMenu()</code> callback method, you can add menu items using one of the +<code>{@link android.view.Menu#add(CharSequence) add()}</code> methods, or by +inflating a menu resource that was <a href="#xml">defined in XML</a>. +Then, register a {@link android.view.ContextMenu} for the View, with +<code>{@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()}</code>.</p> + +<p>For example, here is some code that can be used with the +<a href="{@docRoot}guide/tutorials/notepad/index.html">Notepad application</a> +to add a context menu for each note in the list:</p> +<pre> +public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + menu.add(0, EDIT_ID, 0, "Edit"); + menu.add(0, DELETE_ID, 0, "Delete"); +} + +public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); + switch (item.getItemId()) { + case EDIT_ID: + editNote(info.id); + return true; + case DELETE_ID: + deleteNote(info.id); + return true; + default: + return super.onContextItemSelected(item); + } +} +</pre> + +<p>In <code>onCreateContextMenu()</code>, we are given not only the ContextMenu to +which we will add {@link android.view.MenuItem}s, but also the {@link android.view.View} +that was selected and a {@link android.view.ContextMenu.ContextMenuInfo ContextMenuInfo} object, +which provides additional information about the object that was selected. +In this example, nothing special is done in <code>onCreateContextMenu()</code> — just +a couple items are added as usual. In the <code>onContextItemSelected()</code> +callback, we request the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo} +from the {@code MenuItem}, which provides information about the currently selected item. +All we need from +this is the list ID for the selected item, so whether editing a note or deleting it, +we find the ID with the {@code AdapterContextMenuInfo.info} field of the object. This ID +is passed to the <code>editNote()</code> and <code>deleteNote()</code> methods to perfrom +the respective action.</p> + +<p>Now, to register this context menu for all the items in a {@link android.widget.ListView}, +we pass the entire {@code ListView} to the +<code>{@link android.app.Activity#registerForContextMenu(View)}</code> method:</p> + +<pre>registerForContextMenu(getListView());</pre> +<p>Remember, you can pass any View object to register a context menu. Here, +<code>{@link android.app.ListActivity#getListView()}</code> returns the ListView +object used in the Notepad application's {@link android.app.ListActivity}. As such, each item +in the list is registered to this context menu.</p> + + + +<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> + +<p>A sub menu is created by adding it to an existing {@link android.view.Menu} +with <code>{@link android.view.Menu#addSubMenu(CharSequence) addSubMenu()}</code>. +This returns a {@link android.view.SubMenu} object (an extension of {@link android.view.Menu}). +You can then add additional items to this menu, with the normal routine, using +the <code>{@link android.view.Menu#add(CharSequence) add()}</code> methods. For example:</p> + +<pre> +public boolean onCreateOptionsMenu(Menu menu) { + boolean result = super.onCreateOptionsMenu(menu); + + SubMenu fileMenu = menu.addSubMenu("File"); + SubMenu editMenu = menu.addSubMenu("Edit"); + fileMenu.add("new"); + fileMenu.add("open"); + fileMenu.add("save"); + editMenu.add("undo"); + editMenu.add("redo"); + + return result; +} +</pre> +<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 Submenus when you <a href="#xml">define the parent menu in XML</a>.</p> + + +<h2 id="xml">Define Menus in XML</h2> +<p>Just like Android UI layouts, you can define application menus in XML, then inflate them +in your menu's <code>onCreate...()</code> callback method. This makes your application code cleaner and +separates more interface design into XML, which is easier to visualize.</p> + +<p>To start, create a new folder in your project <code>res/</code> directory called <code>menu</code>. +This is where you should keep all XML files that define your application menus.</p> + +<p>In a menu XML layout, there are +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 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, +above. We start with an XML file named <code>options_menu.xml</code> inside the <code>res/menu/</code> folder:</p> +<pre> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/new_game" + android:title="New Game" /> + <item android:id="@+id/quit" + android:title="Quit" /> +</menu> +</pre> + +<p>Then, in the <code>onCreateOptionsMenu()</code> method, we inflate this resource using +<code>{@link android.view.MenuInflater#inflate(int,Menu) MenuInflater.inflate()}</code>:</p> +<pre> +public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options_menu, menu); + return true; +} +</pre> + +<p>The <code>{@link android.app.Activity#getMenuInflater()}</code> method returns the {@link android.view.MenuInflater} +for our activity's context. We then call <code>{@link android.view.MenuInflater#inflate(int,Menu) inflate()}</code>, +passing it a pointer to our menu resource and the Menu object given by the callback.</code></p> + +<p>While this small sample may seem like more effort, compared to creating the menu items in the +<code>onCreateOptionsMenu()</code> method, this will save a lot of trouble when dealing with more items +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 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 +Resource Types</a> document.</p> + +<h2 id="features">Menu Features</h2> +<p>Here are some other features that can be applied to most menu items.</p> + +<h3 id="groups">Menu groups</h3> +<p>When adding new items to a menu, you can optionally include each item in a group. +A menu group is a collection of menu items that can share certain traits, like +whether they are visible, enabled, or checkable.</p> + +<p>A group is defined by an integer (or a resource id, in XML). A menu item is added to the group when it is +added to the menu, using one of the <code>add()</code> methods that accepts a <var>groupId</var> +as an argument, such as <code>{@link android.view.Menu#add(int,int,int,int)}</code>.</p> + +<p>You can show or hide the entire group with +<code>{@link android.view.Menu#setGroupVisible(int,boolean) setGroupVisible()}</code>; +enable or disable the group with +<code>{@link android.view.Menu#setGroupEnabled(int,boolean) setGroupEnabled()}</code>; +and set whether the items can be checkable with +<code>{@link android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}</code>. +</p> + +<h3 id="checkable">Checkable menu items</h3> +<img align="right" src="{@docRoot}images/radio_buttons.png" alt="" /> +<p>Any menu item can be used as an interface for turning options on and off. This can +be indicated with a checkbox for stand-alone options, or radio buttons for groups of +mutually exlusive options (see the screenshot, to the right).</p> + +<p class="note"><strong>Note:</strong> Menu items in the Icon Menu cannot +display a checkbox or radio button. If you choose to make items in the Icon Menu checkable, +then you must personally indicate the state by swapping the icon and/or text +each time the state changes between on and off.</p> + +<p>To make a single item checkable, use the <code>{@link android.view.MenuItem#setCheckable(boolean) +setCheckable()}</code> method, like so:</p> +<pre> +menu.add(0, VIBRATE_SETTING_ID, 0, "Vibrate") + .setCheckable(true); +</pre> +<p>This will display a checkbox with the menu item (unless it's in the Icon Menu). When the item +is selected, the <code>onOptionsItemSelected()</code> callback is called as usual. It is here that +you must set the state of the checkbox. You can query the current state of the item with +<code>{@link android.view.MenuItem#isChecked()}</code> and set the checked state with +<code>{@link android.view.MenuItem#setChecked(boolean) setChecked()}</code>. +Here's what this looks like inside the +<code>onOptionsItemSelected()</code> callback:</p> +<pre> +switch (item.getItemId()) { +case VIBRATE_SETTING_ID: + if (item.isChecked()) item.setChecked(false); + else item.setChecked(true); + return true; +... +} +</pre> + +<p>To make a group of mutually exclusive radio button items, simply +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 Submenu:</p> +<pre> +SubMenu subMenu = menu.addSubMenu("Color"); +subMenu.add(COLOR_MENU_GROUP, COLOR_RED_ID, 0, "Red"); +subMenu.add(COLOR_MENU_GROUP, COLOR_BLUE_ID, 0, "Blue"); +subMenu.setGroupCheckable(COLOR_MENU_GROUP, true, true); +</pre> +<p>In the <code>setGroupCheckable()</code> method, the first argument is the group ID +that we want to set checkable. The second argument is whether we want the group items +to be checkable. The last one is whether we want each item to be exclusively checkable +(if we set this <em>false</em>, then all the items will be checkboxes instead of radio buttons). +When the group is set to be exclusive (radio buttons), each time a new item is selected, +all other are automatically de-selected.</p> +<p> + +<p class="note"><strong>Note:</strong> +Checkable menu items are intended to be used only on a per-session basis and not saved to the device +(e.g., the <em>Map mode</em> setting in the Maps application is not saved — screenshot above). +If there are application settings that you would like to save for the user, +then you should store the data using <a href="#{@docRoot}guide/topics/data/data-storage.html#pref">Preferences</a>, +and manage them with a {@link android.preference.PreferenceActivity}.</p> + + +<h3 id="shortcuts">Shortcut keys</h3> +<p>Quick access shortcut keys using letters and/or numbers can be added to menu items with +<code>setAlphabeticShortcut(char)</code> (to set char shortcut), <code>setNumericShortcut(int)</code> +(to set numeric shortcut), +or <code>setShortcut(char,int)</code> (to set both)</code>. Case is <em>not</em> sensitive. + +For example:</p> +<pre> +menu.add(0, MENU_QUIT, 0, "Quit") + .setAlphabeticShortcut('q'); +</pre> +<p>Now, when the menu is open (or while holding the MENU key), pressing the "q" key will +select this item.</p> +<p>This shortcut key will be displayed as a tip in the menu item, below the menu item name +(except for items in the Icon Menu).</p> +<p class="note"><strong>Note:</strong> Shortcuts cannot be added to items in a Context Menu.</p> + + +<h3 id="intents">Menu item intents</h3> +<p>If you've read the <a href="{@docRoot}guide/topics/fundamentals.html">Application +Fundamentals</a>, then you're at least a little familiar +with Android Intents. These allow applications to bind with each other, share information, +and perform user tasks cooperatively. Just like your application might fire an Intent to launch a web browser, +an email client, or another Activity in your application, +you can perform such actions from within a menu. +There are two ways to do this: define an Intent and assign it to a single menu item, or +define an Intent and allow Android to search the device for activities and dynamically add a +menu item for each one that meets the Intent criteria.</p> + +<p>For more information on creating Intents and providing your application's services to other applications, +read the <a href="/guide/topics/intents/intents-filters.html">Intents +and Intent Filters</a> document.</p> + +<h4>Set an intent for a single menu item</h4> +<p>If you want to offer a specific menu item that launches a new Activity, then you +can specifically define an Intent for the menu item with the +<code>{@link android.view.MenuItem#setIntent(Intent) +setIntent()}</code> method.</p> + +<p>For example, inside the <code>{@link android.app.Activity#onCreateOptionsMenu(Menu) +onCreateOptionsMenu()}</code> method, you can define a new menu item with an Intent like this:</p> +<pre> +MenuItem menuItem = menu.add(0, PHOTO_PICKER_ID, 0, "Select Photo"); +menuItem.setIntent(new Intent(this, PhotoPicker.class)); +</pre> +<p>Android will automatically launch the Activity when the item is selected.</p> + +<p class="note"><strong>Note:</strong> This will not return a result to your Activity. +If you wish to be returned a result, then do not use <code>setIntent()</code>. +Instead, handle the selection as usual in the <code>onOptionsMenuItemSelected()</code> +or <code>onContextMenuItemSelected()</code> callback and call +<code>{@link android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()}</code>. +</p> + +<h4>Dynamically add intents</h4> + +<p>If there are potentially multiple activities that are relevant to your current +Activity or selected item, then the application can dynamically add menu items that execute other +services.</p> +<p>During menu creation, define an Intent with the category <var>Intent.ALTERNATIVE_CATEGORY</var> and/or +<var>Intent.SELECTED_ALTERNATIVE</var>, the MIME type currently selected (if any), and any other +requirements, the same way as you would satisfy an intent filter to open a new +Activity. Then call +<code>{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) +addIntentOptions()}</code> to have Android search for any services meeting those requirements +and add them to the menu for you. If there are no applications installed +that satisfy the Intent, then no additional menu items are added.</p> + +<p class="note"><strong>Note:</strong> +<var>SELECTED_ALTERNATIVE</var> is used to handle the currently selected element on the +screen. So, it should only be used when creating a Menu in <code>onCreateContextMenu()</code> or +<code>onPrepareOptionsMenu()</code>, which is called every time the Options Menu is opened.</p> + +<p>Here's an example demonstrating how an application would search for +additional services to display on its menu.</p> + +<pre> +public boolean onCreateOptionsMenu(Menu menu){ + super.onCreateOptionsMenu(menu); + + // Create an Intent that describes the requirements to fulfill, to be included + // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE. + Intent intent = new Intent(null, getIntent().getData()); + intent.addCategory(Intent.CATEGORY_ALTERNATIVE); + + // Search for, and populate the menu with, acceptable offering applications. + menu.addIntentOptions( + thisClass.INTENT_OPTIONS, // Menu group + 0, // Unique item ID (none) + 0, // Order for the items (none) + this.getComponentName(), // The current Activity name + null, // Specific items to place first (none) + intent, // Intent created above that describes our requirements + 0, // Additional flags to control items (none) + null); // Array of MenuItems that corrolate to specific items (none) + + return true; +}</pre> + +<p>For each Activity found that provides an Intent Filter matching the Intent defined, a menu +item will be added, using the <var>android:label</var> value of the intent filter as the text +for the menu item. +The <code>{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) addIntentOptions()}</code> method will also return the number of menu items added.</p> +<p>Also be aware that, when <code>addIntentOptions()</code> is called, it will override any and all +menu items in the menu group specified in the first argument.</p> + +<p>If you wish to offer the services of your Activity to other application menus, then you +only need to define an intent filter as usual. Just be sure to include the <var>ALTERNATIVE</var> and/or +<var>SELECTED_ALTERNATIVE</var> values in the <var>name</var> attribute of +a <code><category></code> element in the intent filter. For example:</p> +<pre> +<intent-filter label="Resize Image"> + ... + <category android:name="android.intent.category.ALTERNATIVE" /> + <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> + ... +</intent-filter> +</pre> +<p>read more about writing intent filters in the +<a href="/guide/topics/intents/intents-filters.html">Intents and Intent Filters</a> document.</p> + +<p>For a sample application using this technique, see the +<a href="{@docRoot}guide/samples/NotePad/index.html">Note Pad</a> +sample code.</p> diff --git a/docs/html/guide/topics/ui/themes.jd b/docs/html/guide/topics/ui/themes.jd new file mode 100644 index 0000000..d684512 --- /dev/null +++ b/docs/html/guide/topics/ui/themes.jd @@ -0,0 +1,173 @@ +page.title=Applying Styles and Themes +parent.title=User Interface +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + + <h2>See also</h2> + <ol> + <li><a href="{@docRoot}guide/topics/resources/available-resources.html#stylesandthemes">Style and Theme Resources</a></li> + </ol> +</div> +</div> + +<p>When designing your application, you can use <em>styles</em> and <em>themes</em> to apply uniform formatting to its various screens and UI elements. + +<ul> + <li>A style is a set of one or more formatting attributes that you can apply as a unit to single elements in your layout XML file(s). For example, you could define a style that specifies a certain text size and color, then apply it to instances of a certain type of View element.</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 foreground and background, and sets text sizes and colors for menus, then apply it to the activities of your 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>To create custom styles and themes:</p> +<ol> + <li>Create a file named <code>styles.xml</code> in the your application's <code>res/values</code> directory. Add a root <code><resources></code> node.</li> + <li>For each style or theme, add a <code><style></code> element with a unique <code>name</code> and, optionally, a <code>parent</code> attribute. + The name is used for referencing these styles later, and the parent indicates what style resource to inherit from.</li> + <li>Inside the <code>style</code> element, declare format values in one or more <code><item></code> element. + Each <code>item</code> identifies its style property with a <code>name</code> attribute and defines its style value inside the element.</li> + <li>You can then reference the custom resources from other XML resources, your manifest or application code.</li> +</ol> + + +<h2>Styles</h2> + +<p>Here's an example declaration of a style: </p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="SpecialText" parent="@style/Text"> + <item name="android:textSize">18sp</item> + <item name="android:textColor">#008</item> + </style> +</resources> +</pre> + +<p>As shown, you can use <code><item></code> elements to set specific formatting values for the style. +The <code>name</code> attribute in the <code>item</code> can refer to a standard string, a hex color value, +or a reference to any other resource type.</p> + +<p>Note the <code>parent</code> attribute in the <code>style</code> element. This attribute lets you specify a resource from which the current style will inherit values. The style can inherit from any type of resource that contains the style(s) you want. In general, your styles should always inherit (directly or indirectly) from a standard Android style resource. This way, you only have to define the values that you want to change.</p> + +<p>Here's how you would reference the custom style from an XML layout, in this case, for an EditText element:</p> + +<pre> +<EditText id="@+id/text1" + style="@style/SpecialText" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Hello, World!" /> +</pre> + +<p>Now this EditText widget will be styled as defined by the <code>style</code> example above.</p> + + +<h2>Themes</h2> + +<p>Just like styles, themes are also declared in XML <code><style></code> elements, and are referenced in the same manner. +The difference is that you can add a theme style only to <code><application></code> and <code><activity></code> elements — +they cannot be applied to individual views in the layout.</p> + +<p>Here's an example declaration of a theme:</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="CustomTheme"> + <item name="android:windowNoTitle">true</item> + <item name="windowFrame">@drawable/screen_frame</item> + <item name="windowBackground">@drawable/screen_background_white</item> + <item name="panelForegroundColor">#FF000000</item> + <item name="panelBackgroundColor">#FFFFFFFF</item> + <item name="panelTextColor">?panelForegroundColor</item> + <item name="panelTextSize">14</item> + <item name="menuItemTextColor">?panelTextColor</item> + <item name="menuItemTextSize">?panelTextSize</item> + </style> +</resources> +</pre> + +<p>Notice the use of the at-symbol (@) and the question-mark (?) to reference resources. +The at-symbol indicates that we're referencing a resource previously defined elsewhere (which may be from +this project or from the Android framework). +The question-mark indicates that we're referencing a resource value in the currently loaded theme. This +is done by referring to a specific <code><item></code> by its <code>name</code> value. (E.g., +<em>panelTextColor</em> uses the same color assigned to <em>panelForegroundColor</em>, defined beforehand.) +This technique can be used only in XML resources. +</p> + +<h3>Set the theme in the Manifest</h3> +<p>To set this theme for all the activites of your application, open the Manifest file and +edit the <code><application></code> tag to include the <code>android:theme</code> attribute with the +theme name:</p> + +<pre> +<application android:theme="@style/CustomTheme"> +</pre> + +<p>If you want the theme applied to just one Activity in your application, then add the theme +attribute to the <code><activity></code> tag, instead.</p> + +<p>Just as Android provides other built-in resources, there are several themes that you swap in +without having to write one yourself. For example, you can use the Dialog theme to make your Activity +appear like a dialog box. In the manifest, reference an Android theme like so:</p> + +<pre> +<activity android:theme="@android:style/Theme.Dialog"> +</pre> + +<p>If you like a theme, but want to slightly tweak it, just add the theme as the <code>parent</code> of your custom theme. +For example, we'll modify the <code>Theme.Dialog</code> theme. First, we need to import the parent of the +<code>Dialog</code> theme: <code>Theme</code>. At the top of the <code>resources</code>, add:</p> +<pre> +<style name="Theme" parent="@android:Theme"> + <!-- no modification --> +</style> +</pre> +<p>Now create a a new theme with <code>Theme.Dialog</code> as the parent:</p> +<pre> +<style name="CustomDialogTheme" parent="@android:style/Theme.Dialog"> +</pre> +<p>There it is. We've inherited the Dialog theme, so we can adjust its styles as we like. +So, for each item in the Dialog theme that we want to override, we re-define the value under this style and +then use <var>CustomDialogTheme</var> instead of the <var>Theme.Dialog</var>.</p> + +<h3>Set the theme from the application</h3> +<p>You can also load a theme for an Activity programmatically, if needed. +To do so, use the {@link android.app.Activity#setTheme(int) setTheme()} +method. Note that, when doing so, you must be sure to set the theme <em>before</em> +instantiating any Views in the context, for example, before calling +setContentView(View) or inflate(int, ViewGroup). This ensures that +the system applies the same theme for all of your UI screens. Here's an example:</p> + +<pre> + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + ... + setTheme(android.R.style.Theme_Light); + setContentView(R.layout.linear_layout_3); +} +</pre> + +<p>If you are considering loading a theme programmatically for the main +screen of your application, note that the theme would not be applied +in any animations the system would use to show the activity, which +would take place before your application starts. In most cases, if +you want to apply a theme to your main screen, doing so in XML + is a better approach. </p> + +<p>For detailed information about custom styles and themes and referencing them from your application, see +<a href="{@docRoot}guide/topics/resources/available-resources.html#stylesandthemes">Style +and Theme Resources</a>.</p> + +<p>For information about default themes and styles available, see {@link android.R.style}.</p> + + + + + + 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> +--> |