When developing an Android App the Activity screens that form the user interface should be useable in both portrait and landscape modes. Most Android devices can be used in either orientation so screen support for both is helpful to the user. To achieve this produce layouts for each mode, alternatively design the portrait layout and then wrap it a ScrollView. Here is a screen from a simple App (it converts a loan’s annual interest rate to the monthly rate and vice versa).
Here is the layout for the screen, you can try the following layouts by copying them into a new project in Eclipse (see Copying Code from the Articles for tips). When running the simple example here use the QVGA screen when configuring the Android Virtual Device (AVD).
[code lang=”xml”]<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="120dp"
android:layout_height="wrap_content"
android:text="Interest Rate (%): "/>
<EditText android:id="@+id/inputRate"
android:layout_width="120dp"
android:layout_height="wrap_content" />
</LinearLayout>
<RadioGroup android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton android:id="@+id/radioToMonthly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Yearly to Monthly"
android:checked="true"/>
<RadioButton android:id="@+id/radioToYearly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Monthly to Yearly"/>
</RadioGroup>
<Button android:id="@+id/convert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Convert"/>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="120dp"
android:layout_height="wrap_content"
android:text="Result (%): "/>
<EditText android:id="@+id/result"
android:layout_width="120dp"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>[/code]
When the device is rotated (Ctrl-F11 on the emulator) the bottom of the screen is no longer visible and is not accessible.
One solution is to restrict Android to not switch the screen to landscape for the Activity. Open the AndroidManifest.xml file in the activity declaration element add the attribute screenOrientation and set it to portrait.
[code lang=”xml”]<activity android:name=".main"
android:label="@string/app_name"
android:screenOrientation="portrait">[/code]
This is not very user friendly. Instead of using the screenOrientation attibute a quick fix is to drop the entire layout into a ScrollView (remember to move the xmlns:android attribute from the first LinearLayout element to the ScrollView element). It has to be the entire layout because ScrollView is derived from FrameLayout which only accepts a single child.
[code lang=”xml”]<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!– The Other Elements –>
</LinearLayout>
</ScrollView>
[/code]
A better solution is to explicitly support the landscape orientation. To do this create a folder under the res directory called layout-land. Copy the existing layout XML file from the res/layout folder into the new folder.
Then change the copied file in layout-land to suit the landscape orientation.
This is the modified layout file.
[code lang=”xml”]<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="120dp"
android:layout_height="wrap_content"
android:text="Interest Rate (%): "/>
<EditText android:id="@+id/inputRate"
android:layout_width="120dp"
android:layout_height="wrap_content" />
</LinearLayout>
<RadioGroup android:id="@+id/radioGroup"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton android:id="@+id/radioToMonthly"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Yearly to Monthly"
android:checked="true"/>
<RadioButton android:id="@+id/radioToYearly"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Monthly to Yearly"/>
</RadioGroup>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="@+id/convert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Convert"/>
<TextView android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Result (%): "
android:gravity="right"/>
<EditText android:id="@+id/result"
android:layout_width="120dp"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>[/code]
There were no code changes required to support the landscape orientation, only copying and reworking the original portrait screen design.
An image from the Open Clip Art Library was used in this article: http://openclipart.org/detail/77929/android-phone-line-art-by-shokunin





