| Dirk Dougherty | 22558d0 | 2009-12-10 16:25:06 -0800 | [diff] [blame] | 1 | page.title=UI Framework Changes in Android 1.6 |
| Scott Main | 796ce77 | 2011-02-16 10:04:45 -0800 | [diff] [blame] | 2 | parent.title=Articles |
| 3 | parent.link=../browser.html?tag=article |
| Dirk Dougherty | 22558d0 | 2009-12-10 16:25:06 -0800 | [diff] [blame] | 4 | @jd:body |
| 5 | |
| 6 | <p>Android 1.6 introduces numerous enhancements and bug fixes in the UI |
| 7 | framework. This article highlights two improvements in particular: more flexible |
| 8 | and robust RelativeLayout and easier click listeners. </p> |
| 9 | |
| 10 | <h3>More flexible, more robust RelativeLayout</h3> |
| 11 | |
| 12 | <p>RelativeLayout is the most versatile layout offered by the Android UI toolkit |
| 13 | and can be successfully used to reduce the number of views created by your |
| 14 | applications. This layout used to suffer from various bugs and limitations, |
| 15 | sometimes making it difficult to use without having some knowledge of its |
| 16 | implementation. To make your life easier, Android 1.6 comes with a revamped |
| 17 | RelativeLayout. </p> |
| 18 | |
| 19 | <p>This new implementation not only fixes all known bugs in |
| 20 | RelativeLayout but also addresses its major limitation: the |
| 21 | fact that views had to be declared in a particular order. Consider the following |
| 22 | XML layout:</p> |
| 23 | |
| 24 | <pre><?xml version="1.0" encoding="utf-8"?> |
| 25 | |
| 26 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| 27 | android:layout_width="fill_parent" |
| 28 | android:layout_height="64dip" |
| 29 | android:padding="6dip"> |
| 30 | |
| 31 | <TextView |
| 32 | android:id="@+id/band" |
| 33 | android:layout_width="fill_parent" |
| 34 | android:layout_height="26dip" |
| 35 | |
| 36 | android:layout_below="@+id/track" |
| 37 | android:layout_alignLeft="@id/track" |
| 38 | android:layout_alignParentBottom="true" |
| 39 | |
| 40 | android:gravity="top" |
| 41 | android:text="The Airborne Toxic Event" /> |
| 42 | |
| 43 | <TextView |
| 44 | android:id="@id/track" |
| 45 | android:layout_marginLeft="6dip" |
| 46 | android:layout_width="fill_parent" |
| 47 | android:layout_height="26dip" |
| 48 | |
| 49 | android:layout_toRightOf="@+id/artwork" |
| 50 | |
| 51 | android:textAppearance="?android:attr/textAppearanceMedium" |
| 52 | android:gravity="bottom" |
| 53 | android:text="Sometime Around Midnight" /> |
| 54 | |
| 55 | <ImageView |
| 56 | android:id="@id/artwork" |
| 57 | android:layout_width="56dip" |
| 58 | android:layout_height="56dip" |
| 59 | android:layout_gravity="center_vertical" |
| 60 | |
| 61 | android:src="@drawable/artwork" /> |
| 62 | |
| 63 | </RelativeLayout></pre> |
| 64 | |
| 65 | <p>This code builds a very simple layout—an image on the left with two lines of |
| 66 | text stacked vertically. This XML layout is perfectly fine and contains no |
| 67 | errors. Unfortunately, Android 1.5's RelativeLayout is incapable of rendering it |
| 68 | correctly, as shown in the screenshot below.</p> |
| 69 | |
| 70 | <img src="images/ui-1.6_002.png" style="width: 320px; height: 480px;"> |
| 71 | |
| 72 | <p>The problem is that this layout uses forward references. For instance, the |
| 73 | "band" TextView is positioned below the "track" TextView but "track" is declared |
| 74 | after "band" and, in Android 1.5, RelativeLayout does not know how to handle |
| 75 | this case. Now look at the exact same layout running on Android 1.6:</p> |
| 76 | |
| 77 | <img src="images/ui-1.6.png" style="width: 320px; height: 480px;"> |
| 78 | |
| 79 | <p>As you can see Android 1.6 is now better able to handle forward reference. |
| 80 | The result on screen is exactly what you would expect when writing the |
| 81 | layout.</p> |
| 82 | |
| 83 | <h3>Easier click listeners</h3> |
| 84 | |
| 85 | <p>Setting up a click listener on a button is very common task, but |
| 86 | it requires quite a bit of boilerplate code:</p> |
| 87 | |
| 88 | <pre>findViewById(R.id.myButton).setOnClickListener(new View.OnClickListener() { |
| 89 | public void onClick(View v) { |
| 90 | // Do stuff |
| 91 | } |
| 92 | });</pre> |
| 93 | |
| 94 | <p>One way to reduce the amount of boilerplate is to share a single click |
| 95 | listener between several buttons. While this technique reduces the |
| 96 | number of classes, it still requires a fair amount of code and it still |
| 97 | requires giving each button an id in your XML layout file:</p> |
| 98 | |
| 99 | <pre>View.OnClickListener handler = View.OnClickListener() { |
| 100 | public void onClick(View v) { |
| 101 | switch (v.getId()) { |
| 102 | case R.id.myButton: // doStuff |
| 103 | break; |
| 104 | case R.id.myOtherButton: // doStuff |
| 105 | break; |
| 106 | } |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | findViewById(R.id.myButton).setOnClickListener(handler); |
| 111 | findViewById(R.id.myOtherButton).setOnClickListener(handler);</pre> |
| 112 | |
| 113 | <p>With Android 1.6, none of this is necessary. All you have to do is |
| 114 | declare a public method in your Activity to handle the click |
| 115 | (the method <i>must</i> have one View argument):</p> |
| 116 | |
| 117 | <pre>class MyActivity extends Activity { |
| 118 | public void myClickHandler(View target) { |
| 119 | // Do stuff |
| 120 | } |
| 121 | }</pre> |
| 122 | |
| 123 | <p>And then reference this method from your XML layout:</p> |
| 124 | |
| 125 | <pre><Button android:onClick="myClickHandler" /></pre> |
| 126 | |
| 127 | <p>This new feature reduces both the amount of Java and XML you have to write, |
| 128 | leaving you more time to concentrate on your application.</p> |
| 129 | |
| 130 | <p>The Android team is committed to helping you write applications in the |
| 131 | easiest and most efficient way possible. We hope you find these improvements |
| 132 | useful and we're excited to see your applications on Android Market.</p> |