Android 3.0 is only for large screen devices. However, Android Ice Cream Sandwich is for all small and large screen devices. Developers should create applications that support both large and small screen sizes. This chapter will show the ways of designing user interfaces that support different screen sizes.
The topics covered in this chapter are as follows:
match_parent
and wrap_content
dip
instead of px
There is a vast variety of Android devices and hence there are many different screen sizes.
The following graph (source opensignalmaps.com) shows the Android device fragmentation:
As you see in the graph, there is a vast variety of devices (nearly 4000 distinct devices). This means many different screen sizes and densities. Android scales and resizes the user interface of your Android applications. However, this is not enough all the time. For instance, a user interface designed for a small screen will be magnified for a large screen by the Android. This doesn't look good on large screens. The space on large screens should be used efficiently and the user interfaces of large screens should be different than the user interfaces for small screens. Android provides some APIs for designing the user interfaces that fit the different screen sizes and densities. You should use these APIs to make your application look good on different screen sizes and densities. In this way, user experience of Android applications could be increased.
The things to be considered in designing user interfaces for Android applications are as follows:
match_parent
and wrap_content
could be used to set the
layout_height
and
layout_width
properties of a view. When match_parent
is used, Android expands the view to make its size the same as its parent. When wrap_content
is used, Android expands the view according to its content's size. It is also possible to set the width and height using pixel values. However, it is not a good practice to use pixel values, because the number of pixels change according to the screen properties and a given pixel value is not of the same size in every screen. In the following example, we use the pixel value in order to set the width and height of the view. The layout XML code is shown in the following code block:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="240px" android:layout_height="30px" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:padding="@dimen/padding_medium" android:text="hello world1 hello world 2 hello world 3 hello" tools:context=".Chapter6_1Activity" /> </RelativeLayout>
As you can see in the code, we set layout_width
to 240px
and layout_height
to 30px
. We will execute this application in three different emulators with different screen properties. The emulator properties are as follows:
When this application is executed in the previous emulator configurations, the screens will look like the following:
As you can see in the screenshot, it looks fine on the small screen. However, on the normal screen, the text is cropped and not all the content of the
TextView
component is visible. On the large screen, nothing is visible. This sample shows that using pixel as a width and height value is not a good practice.
Now, we will use
wrap_content
and
match_parent
to set the height and width lengths. The layout XML code will look like the following:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:padding="@dimen/padding_medium" android:text="hello world1 hello world 2 hello world 3 hello" tools:context=".Chapter6_1Activity" /> </RelativeLayout>
When the application is executed with same emulator configurations, the screen will look like the following:
As you can see in this screenshot, the application looks the same in each emulator and screen configurations, and all the content of the
TextView
component is displayed. Thus, using
wrap_content
and
match_parent
is a best practice in designing user interfaces.
Another option for the previous sample is to use the dip
(density independent pixels) value instead of the px
value. In this way, the TextView
component will look nearly the same in different screen sizes. The code will look like the following:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="350dip" android:layout_height="40dip" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:padding="@dimen/padding_medium" android:text="hello world1 hello world 2 hello world 3 hello" tools:context=".Chapter6_1Activity" /> </RelativeLayout>
As you can see in this code, we used the dip
value for the width and height. If you execute this application in the emulators defined in the previous section, it would look like the following:
AbsoluteLayout is a deprecated layout which uses fixed positions for the views in it. AbsoluteLayout
is not a good practice in designing user interfaces because it will not look same in different screen sizes. We will see this with the following example layout:
<?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="96dp" android:layout_y="8dp" android:text="Text Top" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="89dp" android:layout_y="376dp" android:text="Text Bottom" android:textAppearance="?android:attr/textAppearanceLarge" /> </AbsoluteLayout>
As you can see in this XML code, fixed positions are used for the views in AbsoluteLayout
. When this application is executed in the emulators defined in
previous section, it will look like the following:
As you can see in the screen shots, the text at the bottom is not visible on the small screen, but it is visible on the other screens. AbsoluteLayout is not a good practice in user interface design.
Android scales bitmaps according to screen density. However, images will not look good if only one bitmap is provided. The image would look blurry or corrupted. Providing different bitmap drawables for different screen densities is a good practice. In the following screenshot, two image buttons are used. Different bitmap drawables are provided for the first image button and a low density bitmap drawable is provided for the second image button. As you can see in the screenshot, the bitmap in the second image button looks blurry; however, the bitmap in the first image button looks fine.
Android scales the layouts to make them fit to device screens. However, this is not enough in some cases. In Chapter 5, Fragments, we developed an application that lists the books and when a book is clicked, the author of the book is displayed.
The following is the screenshot that is displayed on small screens:
For larger screens, this design is not a good alternative. The user interface will look bad. We should use the space in larger screens efficiently. We can use a different layout for larger screens that combines the two screens displayed on smaller screens. The user interface should look like the following:
The layout files should be put in appropriate folders. For instance, the layout files for large screens should be put in the res/layout-large
folder and for small screens should be put in the res/layout-small
folder.
New screen size qualifiers are introduced with Android 3.2 in addition to existing ones. The new qualifiers are as follows:
sw<N>dp
: This qualifier defines the smallest width. For example, res/layout-sw600dp/
.N
dp, regardless of the screen orientation, the layout file in this folder is used.w<N>dp
: This qualifier defines the exact available width. For example, res/layout-w600dp/
.h<N>dp
: This qualifier defines the exact available height. For example, res/layout-h600dp/
.The nine-patch feature allows the using of stretchable bitmaps as resources. Bitmaps are stretched according to defined stretchable areas. Stretchable areas are defined by a 1-pixel width black line. The following is a sample nine-patch drawable:
The image file should be put into the drawable folder with an extension of .
9.png
. The top and the left black lines define the stretchable area and the bottom and the right black lines define the stretchable area to fit content.
There is a tool called Draw 9-patch that is bundled with Android SDK. You can easily create nine-patch images with this editor.
98.82.120.188