Android is getting popularity, also considering the launch of Google Nexsus One (but do not forget that Android is used by other devices like Nokia and HTC), and therefore programming for Android is the way to personalize the mobile phone. The concepts behind programming are often the same except for the typical characteristics of the device. In this case, mobile phones are simply smaller than a pc, therefore it is mandatory to adapt the look and feel to the screen. In this article there are different ways of how to show the data on a mobile phone with the source code. There are six examples, from the easier to the most difficult, that give the possibility to create an application exactly in the same way we are used to see on every mobile phone.
To create a project with Android, how to set up the environment and the IDE is the theme of the first article about Android http://www.feropluris.com/?q=android_code_software_example_hallo_world_eclipse_emulator
Linear Layout
This is the first step Layout: the easiest way to show data is simply to put it in rows and columns. Good programming practices divide the source code from the view, therefore the core of this application is the file res/layout/main.xml
The code inside is easier to understand after looking the final result in the image.
<?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:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:text="red"
android:gravity="center_horizontal"
android:background="#aa0000"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="green"
android:gravity="center_horizontal"
android:background="#00aa00"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="blue"
android:gravity="center_horizontal"
android:background="#0000aa"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="yellow"
android:gravity="center_horizontal"
android:background="#aaaa00"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:text="row one"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:text="row two"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:text="row three"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:text="row four"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
The root element, LinearLayout, specifies two groups of elements that must be vertical: indeed there are two groups of elements, one made of colors (red, green, blue, yellow) and one made of text (row one, row two, row three, row four). Each of these two groups are LinearLayout themselves, one with horizontal and one with vertical orientation. This is the view. The main file must only invoke it.
The file HelloLinearLayout.java has the code to launch the application. The most important method is onCreate().
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
Relative Layout
For those who are familiar with HTML, there is always the problem to have a fixe
d style and a dynamic one. The fixed style is always the same, does not matter the screen size. The dynamic one adapts itself to view. Generally they are implemented using table, the fixed style, and div, the dynamic, tags. With smaller screens the issue is similar. In the previous example the layout was fixed, in this one is dynamic. Once again, the concept is similar and the view part is totally included in the res/layout/main.xml file.
<?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="fill_parent">
<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="10dip"
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>
The key elements to give a relative position are those starting with layout_ like layout_below, layout_alignParentRight, layout_toLeftOf. It is also possible to specify relationship between nodes using an id. For example the last element, the button Cancel, is positioned relatively to button OK.
Table Layout
Sometimes to put all the elements in correct position, for every device is not possible. To solve this issue, the Table is the most used solution. The file res/layout/main.xml is almost like an HTML table.
<?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:layout_column="1"
android:text="Open..."
android:padding="3dip" />
<TextView
android:text="Ctrl-O"
android:gravity="right"
android:padding="3dip" />
</TableRow>
<TableRow>
<TextView
android:layout_column="1"
android:text="Save..."
android:padding="3dip" />
<TextView
android:text="Ctrl-S"
android:gravity="right"
android:padding="3dip" />
</TableRow>
<TableRow>
<TextView
android:layout_column="1"
android:text="Save As..."
android:padding="3dip" />
<TextView
android:text="Ctrl-Shift-S"
android:gravity="right"
android:padding="3dip" />
</TableRow>
<View
android:layout_height="2dip"
android:background="#FF909090" />
<TableRow>
<TextView
android:text="X"
android:padding="3dip" />
<TextView
android:text="Import..."
android:padding="3dip" />
</TableRow>
<TableRow>
<TextView
android:text="X"
android:padding="3dip" />
<TextView
android:text="Export..."
android:padding="3dip" />
<TextView
android:text="Ctrl-E"
android:gravity="right"
android:padding="3dip" />
</TableRow>
<View
android:layout_height="2dip"
android:background="#FF909090" />
<TableRow>
<TextView
android:layout_column="1"
android:text="Quit"
android:padding="3dip" />
</TableRow>
</TableLayout>
Every cell can contain plain text or a View element.
The main file HelloTableLayout will have the onCreate method that is the same of the other example.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
Grid View
After seeing the basic ways to present the data, it is possible to add more functionality that makes the application like the ones it is used to see.
GridView serves to show data like pictures put all together. This time, the file with the view, res/layout/main.xml, is easier.
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
More code is now demanded. The file HelloGridView.java onCreate method contains more information about the grid and its behaviour.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
}
First an Object ImageAdapter creates the Grid. Secondly the inner method setOnItemClickListener specifies the actions to perform and the object that is clicked.
The class that is invoked is ImageAdapter.
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_4, R.drawable.sample_5,
R.drawable.sample_6, R.drawable.sample_7,
R.drawable.sample_0, R.drawable.sample_1,
R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_4, R.drawable.sample_5,
R.drawable.sample_6, R.drawable.sample_7,
R.drawable.sample_0, R.drawable.sample_1,
R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_4, R.drawable.sample_5,
R.drawable.sample_6, R.drawable.sample_7
};
}
Some methods are not necessary in this example. The method getView manages every image: it creates the position and dimension and an id to identify and distinguish every image.
Tab Layout
This is the second application of the podium. A lot of applications use the tab to navigate and it is particularly useful because of the dimensions of the screen: space is saved.
The Objects used are now TabHost, the node, and TabWidget, to display the tabs.
In the examples, there are three tabs that execute three different operations. Therefore three classes to manage it are reuired, ArtistsActivity,AlbumsActivity, SongsActivity.
For example, ArtistsActivity uses a TextView.
public class ArtistsActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("This is the Artists tab");
setContentView(textview);
}
}
To create a nicer Tab, and to save space, icons are used. An xml file, res/drawable/ic_tab_artists.xml, explains the behaviour.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- When selected, use grey -->
<item android:drawable="@drawable/ic_tab_artists_grey"
android:state_selected="true" />
<!-- When not selected, use white-->
<item android:drawable="@drawable/ic_tab_artists_white" />
</selector>
The two sections say which color using when the tab is selected or not.
The layout file, res/layout/main.xml , declares the Grid.
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" />
</LinearLayout>
</TabHost>
The main file, HelloTabWidget.java , must extend TabActivity.
public class HelloTabWidget extends TabActivity {...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Resources res = getResources(); // Resource object to get Drawables
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Resusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, ArtistsActivity.class);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("artists").setIndicator("Artists",
res.getDrawable(R.drawable.ic_tab_artists))
.setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
intent = new Intent().setClass(this, AlbumsActivity.class);
spec = tabHost.newTabSpec("albums").setIndicator("Albums",
res.getDrawable(R.drawable.ic_tab_albums))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, SongsActivity.class);
spec = tabHost.newTabSpec("songs").setIndicator("Songs",
res.getDrawable(R.drawable.ic_tab_songs))
.setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(2);
}
In the code, there are the information about the properties of the tab, a label and the default way to display them.
There is also the manifest to change a little bit.
<activity android:name=".HelloTabWidget" android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
List View
The top application is the ListView, even if i
n many cases the Grid is used. ListView creates a list of scrollable items. In this case they are a list of String and the Objects ListView and ListAdapter are used.
The layout file, list_item.xml , is similar to the others.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp" >
</TextView>
This time the main class, HelloListView.java, extends ListActivity
public class HelloListView extends ListActivity {...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
Toast.LENGTH_SHORT).show();
}
});
}
The screen is fill with the ListActivity. The ArrayAdapter manages the context and the descriptions of each String. To populate the String, it is possible to add some values in the onCreate method.
static final String[] COUNTRIES = new String[] {
"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
"Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
"Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
"Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
"Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
"Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
"British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
"Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
"Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
"Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
"Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
"Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
"East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
"Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
"Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
"French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
"Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
"Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
"Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
"Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
"Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
"Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
"Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
"Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
"Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
"Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
"Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
"Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
"Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
"Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
"Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
"Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
"Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
"Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
"Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
"The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
"Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
"Ukraine", "United Arab Emirates", "United Kingdom",
"United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
"Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
"Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
};
This is the easiest solution. Generally, to populate the String, a different approach is advisable. In the file res/values/strings.xml simply put the values.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="countries_array">
<item>Bahrain</item>
<item>Bangladesh</item>
<item>Barbados</item>
<item>Belarus</item>
<item>Belgium</item>
<item>Belize</item>
<item>Benin</item>
</string-array>
</resources>
To make it effective, the original onCreate method must be changed.
String[] countries = getResources().getStringArray(R.array.countries_array);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, countries));
Conclusion
The view part is one of the most critical for every mobile phone application. The different size of the screen is usually a constraint and some issues are in common with the normal web applications. Android creates an easy environment and API to create nice views to have applications that are immediately like the ones in every mobile phones. The six examples have different difficulties and they can be used for every application.
Refences
http://developer.android.com/resources/tutorials/views/index.html
http://developer.android.com/resources/tutorials/views/hello-linearlayout.html
http://developer.android.com/resources/tutorials/views/hello-relativelayout.html
http://developer.android.com/resources/tutorials/views/hello-tablelayout.html
http://developer.android.com/resources/tutorials/views/hello-gridview.html
http://developer.android.com/resources/tutorials/views/hello-tabwidget.html
http://developer.android.com/resources/tutorials/views/hello-listview.html
Bookmark/Search this post with: