0% found this document useful (0 votes)
136 views83 pages

MAD Unit - 3

The document discusses various selection widgets and debugging tools in Android, including: 1. ListViews, Spinners, GridViews, ViewPagers, and how to display and fetch information using Dialogs and Fragments. 2. RadioButtons, SeekBars, ToggleButtons and how to implement them with code examples. 3. An explanation of how ListView recycling works to improve performance and reduce memory usage. The document provides code to demonstrate how convertView is used to reuse views. 4. The document discusses displaying different layouts for list items and how to return the correct view type from getItemViewType().

Uploaded by

LavanyaDoopati
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
136 views83 pages

MAD Unit - 3

The document discusses various selection widgets and debugging tools in Android, including: 1. ListViews, Spinners, GridViews, ViewPagers, and how to display and fetch information using Dialogs and Fragments. 2. RadioButtons, SeekBars, ToggleButtons and how to implement them with code examples. 3. An explanation of how ListView recycling works to improve performance and reduce memory usage. The document provides code to demonstrate how convertView is used to reuse views. 4. The document discusses displaying different layouts for list items and how to return the correct view type from getItemViewType().

Uploaded by

LavanyaDoopati
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 83

Unit 3:

Using Selection widgets and Debugging: Using List View, Using the Spinner control, Using the
Grid View Control, Creating an Image Gallery Using the View Pager Control, Using the
Debugging Tool: Dalvik Debug Monitor Service(DDMS), Debugging Application, Using the
Debug Perspective.
Displaying And Fetching Information Using Dialogs and Fragments: What Are Dialogs?,
Selecting the Date and Time in One Application, Fragments, Creating Fragments with java Code,
Creating Special Fragments.

Using Selection widgets and Debugging:


We discussed about widgets and Debugging
 Android architecture
 App structure
 Designing in Design and Text mode
 R.java file
 Manifest
 Logging, Assignments-Converter App, Try me App, etc.
 Widgets like button, textview, edittext, imageview, etc.
We will start out discussion with more widgets.
RadioGroup and RadioButton:
A RadioGroup consists of many radio buttons. Only one of the radio button can checked at once.
The idea is to create one RadioGroup and drag as many RadioButton(s) into it.

private RadioGroup mAttendingRadioGroup;


private RadioButton mResponseRadioButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mAttendingRadioGroup = (RadioGroup) findViewById(R.id.radioGroupId);

mAttendingRadioGroup.setOnCheckedChangeListener(new

MOBILE APPLICATION DEVELOPMENT 143


RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
mResponseRadioButton = (RadioButton) findViewById(checkedId);

Log.d("ID", Integer.toString(mResponseRadioButton.getId()));

switch (mResponseRadioButton.getId()) {
case R.id.yesId:
if (mResponseRadioButton.isChecked()) {
Log.d("YES_RADIO_BUTTON", "YES");
}
break;
case R.id.noId:
if (mResponseRadioButton.isChecked()) {
Log.d("NO_RADIO_BUTTON", "NO");
}
break;

case R.id.mayBeId:
if (mResponseRadioButton.isChecked()) {
Log.d("MAYBE_RADIO_BUTTON", "MAY_BE");
}
break;
}
}
});
}
SeekBar:
SeekBar is a widget that could be really useful when there is some progress or rating to be shown.
private SeekBar mRcbRatingSeekbar;
private TextView mRcbResultTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRcbRatingSeekbar = (SeekBar) findViewById(R.id.idRCBRatingSeekbar);
mRcbResultTextView = (TextView) findViewById(R.id.ratingTextId);
mRcbResultTextView.setText("Rating: " + mRcbRatingSeekbar.getProgress() + "/" +
mRcbRatingSeekbar.getMax());
mRcbRatingSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
{
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Log.d("SEEKBAR", "PROGRESS");
MOBILE APPLICATION DEVELOPMENT 144
mRcbResultTextView.setTextColor(Color.GRAY);
mRcbResultTextView.setText("Rating: " + seekBar.getProgress() + "/" +
seekBar.getMax());
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
Log.d("SEEKBAR", "START");
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.d("SEEKBAR", "STOP");
if (seekBar.getProgress() >= 7) {
mRcbResultTextView.setTextColor(Color.RED);
}
}
});
}

ToggleButton:
This widget has two states-On or Off.
mHideSeekToggleButton = (ToggleButton) findViewById(R.id.toggleButtonId);
mPeekABooTextView = (TextView) findViewById(R.id.peekABooId);

mHideSeekToggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mPeekABooTextView.setVisibility(View.VISIBLE);
} else {
mPeekABooTextView.setVisibility(View.INVISIBLE);
}
}
});

MOBILE APPLICATION DEVELOPMENT 145


Using ListView:
There‘s a component in Android called ―Recycler‖. I drawed a picture based on Romain
Guy presentation at Google IO ‘09.

1. If you have 1 billion items – there are only visible items in the memory + view in recycler.

2. ListView asks for a view type1 first time (getView) x visible items. convertView is null in
getView – you create new view of type1 and return it.

3. ListView asks for a view type1 when one item1 is outside of the window and new item the
same type is comming from the bottom. convertView is not null = item1. You should just
set new data and return convertView back. No need to create view again.

Write a simple code and put System.out to the getView:


public class MultipleItemsList extends ListActivity {

private MyCustomAdapter mAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new MyCustomAdapter();

MOBILE APPLICATION DEVELOPMENT 146


for (int i = 0; i < 50; i++) {
mAdapter.addItem("item " + i);
}
setListAdapter(mAdapter);
}

private class MyCustomAdapter extends BaseAdapter {

private ArrayList mData = new ArrayList();


private LayoutInflater mInflater;

public MyCustomAdapter() {
mInflater =
(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public void addItem(final String item) {


mData.add(item);
notifyDataSetChanged();
}

@Override
public int getCount() {
return mData.size();
}

@Override
public String getItem(int position) {
return mData.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
System.out.println("getView " + position + " " + convertView);
ViewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item1, null);
holder = new ViewHolder();
holder.textView =
(TextView)convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.textView.setText(mData.get(position));
return convertView;
}

public static class ViewHolder {


public TextView textView;
}
}

MOBILE APPLICATION DEVELOPMENT 147


Run the program:

getView was called 9 times. convertView is null for all visible items
02-05 13:47:32.559: INFO/System.out(947): getView 0 null
02-05 13:47:32.570: INFO/System.out(947): getView 1 null
02-05 13:47:32.589: INFO/System.out(947): getView 2 null
02-05 13:47:32.599: INFO/System.out(947): getView 3 null
02-05 13:47:32.619: INFO/System.out(947): getView 4 null
02-05 13:47:32.629: INFO/System.out(947): getView 5 null
02-05 13:47:32.708: INFO/System.out(947): getView 6 null
02-05 13:47:32.719: INFO/System.out(947): getView 7 null
02-05 13:47:32.729: INFO/System.out(947): getView 8 null
Then scroll the list slightly down (until item 10 appears):

convertView is still null because there is still no view in the recycler (border of item1 is still
visible at the top:))
02-05 13:48:25.169: INFO/System.out(947): getView 9 null

MOBILE APPLICATION DEVELOPMENT 148


Let‘s scroll list a little more:

ConvertView is not null: item1 goes off the screen directly to the Recycler and item11 is created
based on item1.

02-05 13:48:42.879: INFO/System.out(947): getView 10 ndroid.widget.LinearLayout@437430f8

scroll more just to check what hapens:

2-05 14:01:31.069: INFO/System.out(947): getView 11 android.widget.LinearLayout@437447d0


02-05 14:01:31.142: INFO/System.out(947): getView 12 android.widget.LinearLayout@43744ff8
02-05 14:01:31.279: INFO/System.out(947): getView 13 android.widget.LinearLayout@43743fa
02-05 14:01:31.350: INFO/System.out(947): getView 14 android.widget.LinearLayout@4374582
02-05 14:01:31.429: INFO/System.out(947): getView 15 android.widget.LinearLayout@4374604
02-05 14:01:31.550: INFO/System.out(947): getView 16 android.widget.LinearLayout@4374687
02-05 14:01:31.669: INFO/System.out(947): getView 17 android.widget.LinearLayout@4374709
02-05 14:01:31.839: INFO/System.out(947): getView 18 android.widget.LinearLayout@437478c
02-05 14:03:30.900: INFO/System.out(947): getView 19 android.widget.LinearLayout@43748df
02-05 14:03:32.069: INFO/System.out(947): getView 20 android.widget.LinearLayout@437430f

Different list items’ layouts:


Let‘s move to the ―more complicated‖ example. How about to add separator somewhere to the
list.

You should do the following:

1. Override getViewTypeCount() – return how many different view layouts you have

2. Override getItemViewType(int) – return correct view type id by position

3. Create correct convertView (depending on view item type) in getView

Simple, isn‘t it? Code snippet:

MOBILE APPLICATION DEVELOPMENT 149


public class MultipleItemsList extends ListActivity {
private MyCustomAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new MyCustomAdapter();
for (int i = 1; i < 50; i++) {
mAdapter.addItem("item " + i);
if (i % 4 == 0) {
mAdapter.addSeparatorItem("separator " + i);
}
}
setListAdapter(mAdapter);
}
private class MyCustomAdapter extends BaseAdapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
private ArrayList mData = new ArrayList();
private LayoutInflater mInflater;
private TreeSet mSeparatorsSet = new TreeSet();
public MyCustomAdapter() {
mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_
SERVICE);
}
public void addItem(final String item) {
mData.add(item);
notifyDataSetChanged();
}
public void addSeparatorItem(final String item) {
mData.add(item);
// save separator position
mSeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
@Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
@Override
public int getCount() {
return mData.size();

MOBILE APPLICATION DEVELOPMENT 150


}
@Override
public String getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
System.out.println("getView " + position + " " + convertView + " type = " + type);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.item1, null);
holder.textView = (TextView)convertView.findViewById(R.id.text);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.item2, null);
holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.textView.setText(mData.get(position));
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
}
Let‘s run what we wrote. Yo will see separators after each 4-th item in the list.

MOBILE APPLICATION DEVELOPMENT 151


In the log – nothing exceptional – all convertView is null for visible items both types.
02-05 15:19:03.080: INFO/System.out(1035): getView 0 null type = 0
02-05 15:19:03.112: INFO/System.out(1035): getView 1 null type = 0
02-05 15:19:03.130: INFO/System.out(1035): getView 2 null type = 0
02-05 15:19:03.141: INFO/System.out(1035): getView 3 null type = 0
02-05 15:19:03.160: INFO/System.out(1035): getView 4 null type = 1
02-05 15:19:03.170: INFO/System.out(1035): getView 5 null type = 0
02-05 15:19:03.180: INFO/System.out(1035): getView 6 null type = 0
02-05 15:19:03.190: INFO/System.out(1035): getView 7 null type = 0
02-05 15:19:03.210: INFO/System.out(1035): getView 8 null type = 0
02-05 15:19:03.210: INFO/System.out(1035): getView 9 null type = 1
Scroll list and see what happens:

02-05 15:19:54.160: INFO/System.out(1035): getView 10 null type = 0

02-05 15:19:57.440: INFO/System.out(1035): getView 11


android.widget.LinearLayout@43744528 type = 0

02-05 15:20:01.310: INFO/System.out(1035): getView 12


android.widget.LinearLayout@43744eb0 type = 0

02-05 15:20:01.880: INFO/System.out(1035): getView 13


android.widget.LinearLayout@437456d8 type = 0

02-05 15:20:02.869: INFO/System.out(1035): getView 14 null type = 1

02-05 15:20:06.489: INFO/System.out(1035): getView 15


android.widget.LinearLayout@43745f00 type = 0

02-05 15:20:07.749: INFO/System.out(1035): getView 16


android.widget.LinearLayout@43747170 type = 0

02-05 15:20:10.250: INFO/System.out(1035): getView 17


android.widget.LinearLayout@43747998 type = 0

MOBILE APPLICATION DEVELOPMENT 152


02-05 15:20:11.661: INFO/System.out(1035): getView 18
android.widget.LinearLayout@437481c0 type = 0

02-05 15:20:13.180: INFO/System.out(1035): getView 19


android.widget.LinearLayout@437468a0 type = 1

02-05 15:20:16.900: INFO/System.out(1035): getView 20


android.widget.LinearLayout@437489e8 type = 0

02-05 15:20:25.690: INFO/System.out(1035): getView 21


android.widget.LinearLayout@4374a8d8 type = 0

Example for Multiple Items List:


package com.test.list;

import android.app.ListActivity;

import android.content.Context;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.TextView;

import java.util.ArrayList;

import java.util.TreeSet;

public class MultipleItemsList extends ListActivity {

private MyCustomAdapter mAdapter;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mAdapter = new MyCustomAdapter();

for (int i = 1; i < 50; i++) {

mAdapter.addItem("item " + i);

if (i % 4 == 0) {

mAdapter.addSeparatorItem("separator " + i);

MOBILE APPLICATION DEVELOPMENT 153


}

setListAdapter(mAdapter);

private class MyCustomAdapter extends BaseAdapter {

private static final int TYPE_ITEM = 0;

private static final int TYPE_SEPARATOR = 1;

private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;

private ArrayList<String> mData = new ArrayList<String>();

private LayoutInflater mInflater;

private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();

public MyCustomAdapter() {

mInflater =
(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

public void addItem(final String item) {

mData.add(item);

notifyDataSetChanged();

public void addSeparatorItem(final String item) {

mData.add(item);

// save separator position

mSeparatorsSet.add(mData.size() - 1);

notifyDataSetChanged();

@Override

public int getItemViewType(int position) {

return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;

MOBILE APPLICATION DEVELOPMENT 154


@Override

public int getViewTypeCount() {

return TYPE_MAX_COUNT;

@Override

public int getCount() {

return mData.size();

@Override

public String getItem(int position) {

return mData.get(position);

@Override

public long getItemId(int position) {

return position;

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder = null;

int type = getItemViewType(position);

System.out.println("getView " + position + " " + convertView + " type = " + type);

if (convertView == null) {

holder = new ViewHolder();

switch (type) {

case TYPE_ITEM:

convertView = mInflater.inflate(R.layout.item1, null);

holder.textView = (TextView)convertView.findViewById(R.id.text);

MOBILE APPLICATION DEVELOPMENT 155


break;

case TYPE_SEPARATOR:

convertView = mInflater.inflate(R.layout.item2, null);

holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);

break;

convertView.setTag(holder);

} else {

holder = (ViewHolder)convertView.getTag();

holder.textView.setText(mData.get(position));

return convertView;

public static class ViewHolder {

public TextView textView;

Using the Spinner control:


In Spinner provides a quick way to select one value from a set of values. Android spinners
are nothing but the drop down-list seen in other programming languages. In a default state,
a spinner shows its currently selected value. It provides a easy way to select a value from a list of
values.

MOBILE APPLICATION DEVELOPMENT 156


In Simple Words we can say that a spinner is like a combo box of AWT or swing where we can
select a particular item from a list of items. Spinner is a sub class of AsbSpinner class.
Here is the XML basic code for Spinner:
<Spinner
android:id="@+id/simpleSpinner "
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Suppose if we need to display a textview and a imageview in spinner item list then arrayadapter is
not enough for that. Here we have to implement custom adapter in our class. Below image of
Spinner and Custom Spinner will make it more clear.

ArraryAdapter:
An adapter is a bridge between UI component and data source that helps us to fill data in UI
component. It holds the data and send the data to adapter view then view can takes the data from
the adapter view and shows the data on different views like as list view, grid view, spinner.
Whenever you have a list of single items which is backed by an array, you can use Array Adapter.
ArrayAdapter in Android:
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
For more details read ArrayAdapter Tutorial as here we will use it in the below example to
explain how Spinner is created in Android.
Example of Spinner In Android Studio:
Example 1: Below is the example in which we display a list of bank names in a spinner and
whenever you select an item the value will be displayed using toast on Mobile screen. Below is
the final output and code:

MOBILE APPLICATION DEVELOPMENT 157


Step 1: Create a new project in Android Studio and name it SpinnerExample.
Select File -> New -> New Project ->. Fill the forms and click "Finish" button.
Step 2: Open res -> layout -> activity_main.xml (or) main.xml and add following code. Here we
will create a Spinner inside Relative Layout.
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Spinner
android:id="@+id/simpleSpinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp" />
</RelativeLayout>
Step 3: Now open app-> java -> package -> MainActivity.java and add the following code. Here
we will use ArrayAdapter to fill the data in Spinner. Also we are using Toast to display when the
item in Spinner is selected.

package example.abhiandriod.spinnerexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements


AdapterView.OnItemSelectedListener{
String[] bankNames={"BOI","SBI","HDFC","PNB","OBC"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Getting the instance of Spinner and applying OnItemSelectedListener on it
Spinner spin = (Spinner) findViewById(R.id.simpleSpinner);
spin.setOnItemSelectedListener(this);

//Creating the ArrayAdapter instance having the bank name list

MOBILE APPLICATION DEVELOPMENT 158


ArrayAdapter aa = new ArrayAdapter(this,android.R.layout.simple_spinner_item,bankNames);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Setting the ArrayAdapter data on the Spinner
spin.setAdapter(aa);
}
//Performing action onItemSelected and onNothing selected
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position,long id) {
Toast.makeText(getApplicationContext(), bankNames[position], Toast.LENGTH_LONG).show();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
Output:
Now the run the program in Emulator and you will see options to choose among bank names
present inside drop down list. You will also see Toast message displaying on the screen when you
will select the particular bank.

Custom Spinner:
Custom Spinner is used to display a spinner item with image, text etc (i.e. creating more custom
list item). It is achieved in Android using custom adapter like base adapter.

MOBILE APPLICATION DEVELOPMENT 159


Using the Grid View Control:
GridView is a view group that display items in two dimensional scrolling grid (rows and
columns), the grid items are not necessarily predetermined but they are automatically inserted to
the layout using a ListAdapter. Users can then select any grid item by clicking on it. GridView is
default scrollable so we don‘t need to use ScrollView or anything else with GridView.
GridView is widely used in android applications. An example of GridView is your
default Gallery, where you have number of images displayed using grid.
Adapter Is Used To Fill Data In Gridview: To fill the data in a GridView we simply
use adapter and grid items are automatically inserted to a GridView using an Adapter which pulls
the content from a source such as an arraylist, array or database. You can read full Adapter tutorial
here.
GridView in Android Studio: Gridview is present inside Containers. From there you can drag
and drop on virtual mobile screen to create it. Alternatively you can also XML code to create it.

Basic GridView code in XML:


<GridView
android:id="@+id/simpleGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numColumns="3"/>

MOBILE APPLICATION DEVELOPMENT 160


Attributes of GridView:
Lets see different attributes of GridView which will be used while designing a custom grid view:
1. id: id is used to uniquely identify a GridView.
Below is the id attribute‘s example code with explanation included in which we don‘t specify the
number of columns in a row that‘s why the GridView behaves like a ListView.
Below is the id attribute example code for Gridview:
<GridView
android:id="@+id/simpleGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
2. numColumns: numColumn define how many columns to show. It may be a integer value,
such as ―5‖ or auto_fit.
auto_fit is used to display as many columns as possible to fill the available space on the screen.
Below is the numColumns example code where we define 4 columns to show in the screen.
<!-- numColumns example code -->
<GridView
android:id="@+id/simpleGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numColumns="4"/> <!-- numColumns set to 4-->

3. Horizontal Spacing: horizontalSpacing property is used to define the default horizontal


spacing between columns. This could be in pixel(px),density pixel(dp) or scale independent
pixel(sp).
Below is the horizontalSpacing example code with explanation included where horizontal spacing
between grid items is 50 dp.
<!--Horizontal space example code in grid view-->>
<GridView
android:id="@+id/simpleGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numColumns="3"
android:horizontalSpacing="50dp"/><!--50dp horizontal space between grid items-->

MOBILE APPLICATION DEVELOPMENT 161


4. VerticalSpacing: Vertical Spacing property used to define the default vertical spacing
between rows. This should be in px, dp or sp.
Below is the verticalSpacing example code with explanation included, where vertical spacing
between grid items is 50dp.
<!-- Vertical space between grid items code -->
<GridView
android:id="@+id/simpleGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numColumns="3"
android:verticalSpacing="50dp"/><!--50dp vertical space set between grid items-->

5. ColumnWidth: ColumnWidth property specifies the fixed width of each column. This
could be in px, dp or sp.
Below is the columnWidth example code. Here column width is 80dp and selected item‘s
background color is green which shows the actual width of a grid item.
The below code is not sufficient to show you the output.
<!--columnWidth in Grid view code-->
<GridView
MOBILE APPLICATION DEVELOPMENT 162
android:id="@+id/simpleGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numColumns="3"
android:columnWidth="80dp"
android:listSelector="#0f0"/><!--define green color for selected item-->

GridView Example Using Different Adapters In Android Studio:


An adapter is a bridge between UI component and data source that helps us to fill data in UI
component. It holds the data and sends the data to adapter view, then view can takes the data from
the adapter view and shows the data on different views like as list view, grid view, spinner etc.
GridView and ListView both are subclasses of AdapterView and it can be populated by
binding to an Adapter, which retrieves the data from an external source and creates a View that
represents each data entry. In android commonly used adapters which fill data in GridVieware:
1. Array Adapter
2. Base Adapter
3. Custom Array Adapter
Now we explain these adapters in detail:
1. Avoid Array Adapter To Fill Data In GridView:
Whenever you have a list of single items which is backed by an array, you can use ArrayAdapter.
For instance, list of phone contacts, countries or names.
By default, ArrayAdapter expects a Layout with a single TextView, If you want to use more
complex views means more customization in grid items, please avoid ArrayAdapter and use
custom adapters.
ArrayAdapter adapter = new ArrayAdapter<String>(this,R.layout.ListView,R.id.textView,String
Array);
2. GridView Using Base Adapter In Android:
Base Adapter is a common base class of a general implementation of an Adapter that can be used
in GridView. Whenever you need a customized grid view you create your own adapter and extend
base adapter in that. Base Adapter can be extended to create a custom Adapter for displaying
custom grid items. ArrayAdapter is also an implementation of BaseAdapter.
Example of GridView using Base Adapter in Android Studio: Below is the example
of GridView in Android, in which we show the Android logo‘s in the form of Grids. In this
example firstly we create an int type array for logo images and then call the Adapter to set the data
in the GridView. In this we create a CustomAdapter by extending BaseAdapter in it. At Last we
implement setOnItemClickListener event on GridView and on click of any item we send that item
to another Activity and show the logo image in full size.
Below you can download code, see final output and step by step explanation of the example.
MOBILE APPLICATION DEVELOPMENT 163
Step 1: Create a new Android project in Android Studio and fill all the required details. In our
case we have named GridViewExample and package com.example.gourav.GridViewExample
Step 2: Open activity_main.xml and paste the below code. In this we have created a Grid view
insideLinear Layout and also set number of columns to 3.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--
GridView with 3 value for numColumns attribute
-->
<GridView
android:id="@+id/simpleGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:footerDividersEnabled="false"
android:padding="1dp"
android:numColumns="3" />
</LinearLayout>
Step 3: : Create a new XML file and paste the below code. We have named
activity_gridview.xml.
In this step we create a new XML file and add a ImageView in it. This file is used in
CustomAdapter to set the logo images
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="1dp"
android:orientation="vertical">
<ImageView
MOBILE APPLICATION DEVELOPMENT 164
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="120dp"
android:scaleType="fitXY"
android:layout_gravity="center_horizontal"
android:src="@drawable/logo1" />
</LinearLayout>
Step 4:Now open drawable folder and save small size png images of different logo‘s and name
them like logo1,logo2 and etc.
Step 5: Now open MainActivity.java and paste the below code. If your package name is different,
don‘t copy it.
In this step firstly we get the reference of GridView and then create a int type array for Android
logo‘s. After that we call the CustomAdapter and pass the array in it. At Last we implement
setOnItemClickListener event on GridView and on click of any item we send that item to another
Activity to show the logo image in Full Size. I have added comments in code to help you to
understand the code easily so make you read the comments.
package com.example.gourav.GridViewExample;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
public class MainActivity extends AppCompatActivity {
GridView simpleGrid;
int logos[] = {R.drawable.logo1, R.drawable.logo2, R.drawable.logo3, R.drawable.logo4,
R.drawable.logo5, R.drawable.logo6, R.drawable.logo7, R.drawable.logo8, R.drawable.logo9,
.drawable.logo10, R.drawable.logo11, R.drawable.logo12, R.drawable.logo13};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
simpleGrid = (GridView) findViewById(R.id.simpleGridView); // init GridView
// Create an object of CustomAdapter and set Adapter to GirdView
CustomAdapter customAdapter = new CustomAdapter(getApplicationContext(), logos);
simpleGrid.setAdapter(customAdapter);
// implement setOnItemClickListener event on GridView
simpleGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// set an Intent to Another Activity
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("image", logos[position]); // put image data in Intent
startActivity(intent); // start Intent
}
});

MOBILE APPLICATION DEVELOPMENT 165


}
}
Step 6: Create a new class CustomAdapter and paste the below code. In this step we create a
CustomAdapter class by extending BaseAdapter in it. In this step we set the logo image‘s in the
grid items. I have added comments in code to help you to understand the code easily so make you
read the comments.
package com.example.gourav.GridViewExample;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
public class CustomAdapter extends BaseAdapter {
Context context;
int logos[];
LayoutInflater inflter;
public CustomAdapter(Context applicationContext, int[] logos) {
this.context = applicationContext;
this.logos = logos;
inflter = (LayoutInflater.from(applicationContext));
}
@Override
public int getCount() {
return logos.length;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.activity_gridview, null); // inflate the layout
ImageView icon = (ImageView) view.findViewById(R.id.icon); // get the reference of
ImageView
icon.setImageResource(logos[i]); // set logo images
return view;
}
}
Step 7: Now Create a new XML file named activity_second and paste the below code in it.
In this step we create an XML file for our Second Activity to display the logo image in full size.
<?xml version="1.0" encoding="utf-8"?>

MOBILE APPLICATION DEVELOPMENT 166


<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="#fff"
tools:context="com.example.gourav.GridViewExample.SecondActivity">
<ImageView
android:id="@+id/selectedImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:scaleType="fitXY" />
</RelativeLayout>
Step 8: Now Create a new Activity with name SecondActivity.class and add below code in it.
In this step we create a new Activity in which firstly we initiate the ImageView and then get the
Image from our Previous Activity by using Intent object and set the same in the ImageView.
package com.example.gourav.GridViewExample;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
public class SecondActivity extends AppCompatActivity {
ImageView selectedImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
selectedImage = (ImageView) findViewById(R.id.selectedImage); // init a ImageView
Intent intent = getIntent(); // get Intent which we set from Previous Activity
selectedImage.setImageResource(intent.getIntExtra("image", 0)); // get image from Intent
and set it in ImageView
}
}
Output: Now run the App and you will see different Android images in GridView. Click on the
any image and full size of it will open up.

3. GridView Example Using Custom ArrayAdapter In Android Studio:


ArrayAdapter is also an implementation of BaseAdapter so if we want more customization then
we create a custom adapter and extend ArrayAdapter in that. Here we are creating GridView
using custom array adapter.
Example of GridView using Custom Adapter: Example of Grid View using custom
arrayadapter to show birds in the form of grids. Below is the code and final output:
MOBILE APPLICATION DEVELOPMENT 167
Below you can download code, see final output and step by step explanation of the topic.

Step 1: Create a new project and name it GridViewExample.


Step 2: Now open app -> res -> layout -> activity_main.xml (or) main.xml and add following
code :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="abhiandroid.com.gridviewexample.MainActivity">

<GridView
android:id="@+id/simpleGridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="3"/>

</RelativeLayout>
Step 3: Create a new layout Activity in app -> res-> layout-> new activity and name it
grid_view_items.xml and add following code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/grid_view_items"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"

MOBILE APPLICATION DEVELOPMENT 168


android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="abhiandroid.com.gridviewexample.GridViewItems">

<ImageView
android:id="@+id/imageView"
android:layout_width="150dp"
android:layout_height="150dp"
android:padding="5dp"
android:scaleType="fitXY"
android:src="@drawable/ic_launcher"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/activity_horizontal_margin"
android:text="Demo"
android:textColor="#000"
android:layout_below="@+id/imageView"
android:layout_centerHorizontal="true"
android:layout_marginTop="13dp" />
</RelativeLayout>
Step 4: Now open app -> java -> package -> MainActivity.java
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.GridView;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {


GridView simpleList;
ArrayList birdList=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
simpleList = (GridView) findViewById(R.id.simpleGridView);
birdList.add(new Item("Bird 1",R.drawable.b1));
birdList.add(new Item("Bird 2",R.drawable.b2));
birdList.add(new Item("Bird 3",R.drawable.b3));

MOBILE APPLICATION DEVELOPMENT 169


birdList.add(new Item("Bird 4",R.drawable.b4));
birdList.add(new Item("Bird 5",R.drawable.b5));
birdList.add(new Item("Bird 6",R.drawable.b6));
MyAdapter myAdapter=new MyAdapter(this,R.layout.grid_view_items,birdList);
simpleList.setAdapter(myAdapter);
}
}
Step5 : Create a new Class src -> package -> MyAdapter.java and add the following code:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class MyAdapter extends ArrayAdapter {
ArrayList birdList = new ArrayList<>();
public MyAdapter(Context context, int textViewResourceId, ArrayList objects) {
super(context, textViewResourceId, objects);
birdList = objects;
}
@Override
public int getCount() {
return super.getCount();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService (Context.LAYOUT
_ INFLATER _SERVICE);
v = inflater.inflate(R.layout.grid_view_items, null);
TextView textView = (TextView) v.findViewById(R.id.textView);
ImageView imageView = (ImageView) v.findViewById(R.id.imageView);
textView.setText(birdList.get(position).getbirdName());
imageView.setImageResource(birdList.get(position).getbirdImage());
return v;
}
}
Step 6: Create a new Class src -> package -> Item.java and add the below code:
public class Item {
String birdListName;
int birdListImage;
public Item(String birdName,int birdImage)
{
this.birdListImage=birdImage;

MOBILE APPLICATION DEVELOPMENT 170


this.birdListName=birdName;
}
public String getbirdName()
{
return birdListName;
}
public int getbirdImage()
{
return birdListImage;
}
}
Output:
Now run the App and you will see different bird images in GridView.

Creating an Image Gallery:


Gallery is a view used to show items in a center locked, horizontal scrolling list and user will
select a view and then user selected view will be shown in the center of the Horizontal list. The
items in Gallery are added using Adapter just like in ListView or GridView.

Basic Gallery XML Code:


<Gallery
android:id="@+id/simpleGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/ >
Adapter Used To Fill Images In Gallery:
Adapters works as a bridge between AdapterView and data source. For filling data(images) in
Gallery we need to use Adapters. BaseAdapter is parent adapter for all other adapters so we
mainly used it for displaying data in Gallery list.

MOBILE APPLICATION DEVELOPMENT 171


BaseAdapter:
BaseAdapter is a common base class of a general implementation of an Adapter that can be used
in ListView, GridView, Gallery etc. Base Adapter can be extended to create a custom Adapter for
displaying a custom list items.
Here is the code of Custom Adapter when we extends the BaseAdapter in that:
public class CustomAdapter extends BaseAdapter {
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
return null;
}
In the above code snippet we see the overrided methods of BaseAdapter which are used to set the
data in a list, grid or a Gallery. From there we mainly used two functions getCount() and
getView().
 getView(): This method called automatically for all items of Gallery (similar to list viewin
which getView() method called for each item of ListView)
 getCount(): This method returns the total number of items to be displayed in a list. It
counts the value from array list size() method or an array‘s length.

Steps for Implementation of Android Gallery View:


1. Get the reference of Gallery in class using findViewById() method, or you can also create
an object dynamically.
2. Create an array of Images and call the adapter using Gallery view‘s object.

MOBILE APPLICATION DEVELOPMENT 172


3. Create a Custom adapter class which extends BaseAdapter to bind the Gallery view with a
series of ImageViews.

Methods of Gallery In Android:


Let‘s we discuss some important methods of Gallery that may be called in order to manage the
Gallery.
1. SetAnimationDuration (int): This method is used to set the duration for how long a
transition animation should run (in milliseconds) when layout has changed.
Below we set the duration for how long a transition animation should run when layout has
changed.
Gallery simpleGallery = (Gallery) findViewById(R.id.simpleGallery); // get the reference of
Gallery
simpleGallery.setAnimationDuration(3000); // set 3000 milliseconds for animation duration
between items of Gallery

2. SetSpacing (int): This method is used to set the spacing between items in a Gallery.
Below we set the spacing between the items of Gallery.
Gallery simpleGallery = (Gallery) findViewById(R.id.simpleGallery); // get the reference of
Gallery
simpleGallery.setSpacing(5); // set space between the items of Gallery

MOBILE APPLICATION DEVELOPMENT 173


3. SetUnselectedAlpha (float): This method is used to set the alpha on the items that are not
selected.
Below we set the alpha value for unselected items of Gallery.
Gallery simpleGallery = (Gallery) findViewById(R.id.simpleGallery); // get the reference of
Gallery
simpleGallery.setUnselectedAlpha(0.80f); // set 0.25 value for the alpha of unselected items of
Gallery

Attributes of Gallery:
Now let‘s we discuss some common attributes of a Gallery that helps us to configure it in our
layout (xml).
1. id: id attribute is used to uniquely identify a Gallery.
Below we set the id of the Gallery that is used to uniquely identify it.
<Gallery
android:id="@+id/simpleGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/ > < !-- id of Gallery used to uniquely identify it -->
2. Padding: This attribute is used to set the padding from left, right, top or bottom side of a
Gallery.
 paddingRight: This attribute is used to set the padding from the right side of a Gallery.
 paddingLeft: This attribute is used to set the padding from the left side of a Gallery.
 paddingTop: This attribute is used to set the padding from the top side of a Gallery.
 paddingBottom: This attribute is used to set the padding from the bottom side of a Gallery.
 Padding: This attribute is used to set the padding from the all the side‘s of a Gallery.
Below we set the 10dp padding from all the sides of a Gallery
<Gallery
android:id="@+id/simpleGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"/> <!-- 10dp padding from all the sides of Gallery -->
3. Background: This attribute is used to set the background of a Gallery. We can set a color or a
drawable in the background of a Gallery:
Below is the example code with explanation included in which we set the black color in the
background of Gallery.
<Gallery
android:id="@+id/simpleGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
MOBILE APPLICATION DEVELOPMENT 174
android:background="#000" /> <!-- black background color of Gallery -->
Setting padding In Gallery In Java class:
Gallery simpleGallery=(Gallery)findViewById(R.id.simpleGallery); // get the reference of
Gallery
simpleGallery.setBackgroundColor(Color.BLACK); // set black color in the background of
Gallery
4. AnimationDuration: This attribute is used to set the duration for how long a
transition animation should run (in milliseconds) when layout has changed. We can also set the
animation duration programmatically means in java class by using setAnimationDuration(int).
Below we set the duration for how long a transition animation should run when layout has
changed.
<Gallery
android:id="@+id/simpleGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:animationDuration="3000" />
<!-- set 100 milliseconds for animation duration between items of Gallery -->
5. Spacing: This attribute is used to set the spacing between items in a Gallery. We can also set
the spacing between items programmatically means in java class by using setSpacing() method.
Below we set the spacing between the items of Gallery.
<Gallery
android:id="@+id/simpleGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:spacing="5dp" />
<!-- set 5dp space between the items of Gallery -->
6. UnselectedAlpha: This attribute is used to set the alpha on the items that are not selected. Must
be a floating point value, such as ―5‖. We can also set the alpha of items programmatically means
in java class by using setUnselectedAlpha(float) method.
Below we set the alpha value for unselected items of Gallery.
<Gallery
android:id="@+id/simpleGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:unselectedAlpha="0.25" />
<!-- set 0.25 value for the alpha of unselected items of Gallery -->

Gallery Example In Android Studio:


Below is the example of Gallery in which we display a ImageView and Gallery with number of
items(images). Firstly we create an array of images id‘s and then set the adapter to fill the data in
the Gallery. In this we create custom adapter class in which we extends BaseAdapter class. We
also perform setOnItemClickListener event so whenever a user click on any item of Gallery the
selectable item(image) is displayed in the ImageView.
Below you can download code, see final output and step by step explanation of example:

MOBILE APPLICATION DEVELOPMENT 175


Step 1: Create a new project and name it GalleryExample
Step 2: Open res -> layout ->activity_main.xml (or) main.xml and add following code:
<LinearLayout 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"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">

<!-- create a ImageView and Gallery -->


<ImageView
android:id="@+id/selectedImageView"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:scaleType="fitXY" />

<Gallery
android:id="@+id/simpleGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:unselectedAlpha="0.80" />

</LinearLayout>
Step 3: Open src -> package -> MainActivity.java
In this step we open MainActivity and add the code for initiate the ImageView and Gallery.
Firstly we create an array of images id‘s and then set the adapter to fill the data in the Gallery. We
MOBILE APPLICATION DEVELOPMENT 176
also perform setOnItemClickListener event so whenever a user click on any item of Gallery the
selectable item(image) is displayed in the ImageView.
package example.abhiandroid.galleryexample;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Gallery;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

Gallery simpleGallery;
CustomGalleryAdapter customGalleryAdapter;
ImageView selectedImageView;
// array of images
int[] images = {R.drawable.image1, R.drawable.image2, R.drawable.image3,
R.drawable.image4, R.drawable.image5, R.drawable.image6, R.drawable.image7,
R.drawable.image8, R.drawable.image9, R.drawable.image10, R.drawable.image11,
R.drawable.image12, R.drawable.image13};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
simpleGallery = (Gallery) findViewById(R.id.simpleGallery); // get the reference of Gallery
selectedImageView = (ImageView) findViewById(R.id.selectedImageView); // get the
reference of ImageView
customGalleryAdapter = new CustomGalleryAdapter(getApplicationContext(), images); //
initialize the adapter
simpleGallery.setAdapter(customGalleryAdapter); // set the adapter
simpleGallery.setSpacing(10);
// perform setOnItemClickListener event on the Gallery
simpleGallery.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// set the selected image in the ImageView
selectedImageView.setImageResource(images[position]);

}
});
}
}

MOBILE APPLICATION DEVELOPMENT 177


Step 4: Create a new class CustomGalleryAdapter.java inside package and add the following
code. In this step we create a CustomGalleryAdapter in which we extend BaseAdapter and
implement the overrided methods. In this we create a ImageView at run time in getView method
and finally set the image in the ImageView.
package example.abhiandroid.galleryexample;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
public class CustomGalleryAdapter extends BaseAdapter {
private Context context;
private int[] images;
public CustomGalleryAdapter(Context c, int[] images) {
context = c;
this.images = images;
}
// returns the number of images
public int getCount() {
return images.length;
}
// returns the ID of an item
public Object getItem(int position) {
return position;
}
// returns the ID of an item
public long getItemId(int position) {
return position;
}
// returns an ImageView view
public View getView(int position, View convertView, ViewGroup parent) {
// create a ImageView programmatically
ImageView imageView = new ImageView(context);
imageView.setImageResource(images[position]); // set image in ImageView
imageView.setLayoutParams(new Gallery.LayoutParams(200, 200)); // set ImageView
param
return imageView;
}
}
Using the View Pager Control:
ViewPager in Android is a class that allows the user to flip left and right through pages of data.
This class provides the functionality to flip pages in app.

MOBILE APPLICATION DEVELOPMENT 178


It is a widget found in the support library. To use it you‗ll have to put the element inside your
XML layout file that‘ll contain multiple child views. It is similar to what a ListAdapter does for a
ListView.
ViewPager is most often used along with fragment which is convenient way to manage the life
cycle of each page. ViewPager class works with PagerAdapter which provides pages.
Basic ViewPager XML Code:
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
Steps for Implementing ViewPager:
There are three important steps to implement ViewPager:
1.) A layout(that contains ViewPager) for the MainActivity.
2.) FragmentPagerAdapter/FragmentStatePagerAdapter class which controls the fragments to be
shown on page swipes.
3.) Fragments to be shown on swiping the screen.

PagerAdapter in ViewPager:
There is a base class called PagerAdapter providing the adapter to populate pages inside of a
ViewPager.

MOBILE APPLICATION DEVELOPMENT 179


When you implement a PagerAdapter, you must override the following
methods at minimum:
1. InstantiateItem(ViewGroup, int): This method should create the page for the given
position passed to it as an argument. We inflate() our layout resource to create the hierarchy of
view objects and then set resource for the ImageView in it. Finally, the inflated view is added to
the container (which should be the ViewPager) and return it as well.
public Object instantiateItem(ViewGroup container, int position) {
View itemView = mLayoutInflater.inflate(R.layout.pager_item, container, false);
ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);
imageView.setImageResource(mResources[position]);
container.addView(itemView);
return itemView;
}
2. DestroyItem(ViewGroup, int, Object): Removes the page from the container for the given
position. We simply removed object using removeView but could‘ve also
used removeViewAt() by passing it the position.
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout)object);
}
3. GetCount(): This method should return the number of views available, i.e., number of pages to
be displayed/created in the ViewPager.
public int getCount() {
return mResources.length;
}
4. IsViewFromObject(View, Object): The object returned by instantiateItem() is a key/identifier.
This method checks whether the View passed to it (representing the page) is associated with that
key or not. It is required by a PagerAdapter to function properly.
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
Implementation of PagerAdapter:
PagerAdapter is responsible for creating the content of each page. You‘ll most likely want to use
one of the following two implementation of PagerAdapter:
Using FragmentPagerAdapter to Implement PagerAdapter:
1. Usually to display sliding fragments two methods of FragmentPagerAdapter are used,
getCount() and getItem(). The first one returns the number of fragments to be displayed, and the
second one is used to display the actual fragment & it should be used when we need to store the
whole fragment in memory.
2. It is an implementation of PagerAdapter class that represents each page as Fragment that is
persistently kept in the fragment manager as long as the user can return to the page, hence best to
use when there‘s a fixed small set of screens to be navigated through.
3. It works even better when the content of the fragments are static than something that constantly
changes or gets updated.

MOBILE APPLICATION DEVELOPMENT 180


4. When using FragmentPagerAdapter the host ViewPager must have a valid ID set. It stores the
previous data which is fetched from the adapter. It stores the whole fragment in memory and
could increase a memory overhead if large amount of fragments are used in the ViewPager.
FragmentPagerAdapter code:
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List mFragmentList = new ArrayList<>();
private final List mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager)
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Using FragmentStatePagerAdapter for Implementation of PagerAdapter:
1. Each page is a fragment which gets destroyed as soon as it‘s not visible to the user, i.e. keeping
the saved state of that fragment. Due to this behavior it consumes much less memory .
2. It takes the new value from the adapter every-time it is executed. It only stores the
savedInstanceState of fragments, and destroys all the fragments when they lose focus.
3. It should be used when we have to use dynamic fragments, like fragments with widgets, as their
data could be stored in the savedInstanceState. Also it won‘t affect the performance even if there
are large number of fragments.
PagerTitleStrip:
You can add PagerTitleStrip to ViewPager in layout xml file to display title for each page.
PagerTitleStrip helps to identify previous, current and next pages of a viewpager. PagerTitleStrip
displays next, current and previous page titles of view pager at top or bottom of the screen.
PagerTitleStrip gets page title from view pager adapter.
The getPageTitle() method supplies a title to the page title strip that appears at the top of the
screen.
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position); }

MOBILE APPLICATION DEVELOPMENT 181


Optional you can also include this code in the activity_main.xml file:
<android.support.v4.view.PageTitleStrip
android:id="@+id/pager_title_strip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top:
android:background="#008080"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#FFFFFF"
/>
ViewPager Example Using Fragments in Android Studio:
Example 1 – ViewPager with Fragment
Below is the first example example of ViewPager in which we will learn how to create a simple
ViewPager Tabs with four Fixed Tabs using FragmentPagerAdapter.

Step 1: Create a new project and name it AndroidViewPagerExample.


Step 2: Download three images Apple,Orange and Grapes from the web. Now save those images
in the drawable folder of your project.
Step 3: Now open res -> layout -> activity_main.xml and add following code:
Add a new xml file inside/res/layoutfolder, with name activity_main.xml. We should have the
/res/layout/activity_main.xml file that consists of a LinearLayout with vertical orientation, that
includes a ViewPager.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"

MOBILE APPLICATION DEVELOPMENT 182


android:background="@drawable/backround_blue"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
tools:context=".MainActivity"/>
</LinearLayout>
Step 4: Add a new xml file inside/res/drawable, with name activity backround_blue.xml. It is for
setting the background.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="90"
android:endColor="#3124dc"
android:startColor="#062539"
android:type="linear" />
</shape>
Step 5: Now open app -> java -> package -> MainActivity.java and add the following code:
MainActivity.java
This is the Activity in which we are going to create a ViewPager instance and set its
FragmentPagerAdapter. It is used to display sliding fragments. Two methods of
FragmentPagerAdapter are used, getCount(returns the number of fragments to be displayed)
and getItem(used to display the actual fragment).
package com.abhiandroid.viewpagerexample;

import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import com.abhiandroid.viewpagerexample.myapplication1.R;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}

MOBILE APPLICATION DEVELOPMENT 183


@Override
public android.support.v4.app.Fragment getItem(int pos) {
switch (pos) {
case 0:
return FragmentViewPager.newInstance(getString(R.string.title_section1), R.drawable.apple);
case 1:
return FragmentViewPager.newInstance(getString(R.string.title_section2), R.drawable.orange);
case 2:
return FragmentViewPager.newInstance(getString(R.string.title_section3), R.drawable.grapes);
default:
return FragmentViewPager.newInstance(getString(R.string.title_section1), R.drawable.apple);
}
}

@Override
public int getCount() {
return 3;
}
}
Step 6: Create the layout of the main FragmentViewPager
Add a new xml file inside /res/layout folder, with name fragment_main.xml. We should have
the /res/layout/fragment_main.xml file
It is a simple layout xml for the FragmentViewPager.class, that consists of a LinearLayout with
vertical orientation, that includes a TextView and an ImageView.
<LinearLayout 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"
android:background="#00000000"
android:orientation="vertical">

<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="44dp"
android:textColor="#ffffff"
android:textSize="60dp" />

<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="44dp" />

MOBILE APPLICATION DEVELOPMENT 184


</LinearLayout>
Step 7: Create the source code of the main FragmentViewPager support.v4.app.Fragment
FragmentViewPager.java
package com.abhiandroid.viewpagerexample;

/**
* Created by abhiandroid
*/
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.abhiandroid.viewpagerexample.myapplication1.R;
public class FragmentViewPager extends android.support.v4.app.Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
TextView tv = (TextView) v.findViewById(R.id.title);
tv.setText(getArguments().getString("text"));
ImageView imageView = (ImageView) v.findViewById(R.id.image);
imageView.setBackgroundResource(getArguments().getInt("img"));
return v;
}
public static FragmentViewPager newInstance(String text, int image) {
FragmentViewPager f = new FragmentViewPager();
Bundle b = new Bundle();
b.putString("text", text);
b.putInt("img", image);
f.setArguments(b);
return f;
}
}
Output:
Now run the project and swipe from left to right or vice versa to see different fruit names and
images on screen.
Using the Debugging Tool:
The Android Studio version is also called the debugger. It allows us to monitor our application in
real time, and can provide additional insight regarding a connected device or emulator. Let's walk
through using the debugger in Android Studio, to familiarize ourselves with this process and make
future bugs easier to track down and address.
First, let's remove the two Log messages we added in the last lesson:

MOBILE APPLICATION DEVELOPMENT 185


RestaurantsActivity.java:
public class RestaurantsActivity extends AppCompatActivity {
@Bind(R.id.locationTextView) TextView mLocationTextView;
@Bind(R.id.listView) ListView mListView;

private String[] restaurants = new String[] {"Sweet Hereafter", "Cricket", "Hawthorne Fish
House", "Viking Soul Food",
"Red Square", "Horse Brass", "Dick's Kitchen", "Taco Bell", "Me Kha Noodle Bar",
"La Bonita Taqueria", "Smokehouse Tavern", "Pembiche", "Kay's Bar", "Gnarly Grey",
"Slappy Cakes", "Mi Mero Mole" };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurants);
ButterKnife.bind(this);

ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,


restaurants);
mListView.setAdapter(adapter);

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String restaurant = ((TextView)view).getText().toString();
Toast.makeText(RestaurantsActivity.this, restaurant, Toast.LENGTH_LONG).show();
}
});

Intent intent = getIntent();


String location = intent.getStringExtra("location");

mLocationTextView.setText("Here are all the restaurants near: " + location);


}
}
Breakpoints:
Next, in order to pause the code at a given location, we need to add something called a breakpoint.
A breakpoint is a language-agnostic term meaning the location at which code is intentionally
paused.
Placing Breakpoints:
We can insert a breakpoint (or even multiple breakpoints) where we would like our code to pause.
There are several ways to add a breakpoint.
1. Click the line where you would like to add a breakpoint. Then, select Run > Toggle Line
Breakpoint.

MOBILE APPLICATION DEVELOPMENT 186


A red circle will appear directly to the left of this line of code. The area this red circle resides in is
known as the gutter:

To remove a breakpoint in the same fashion, we can simply select the same line, then select Run >
Toggle Line Breakpoint again to toggle it off.
1. We can also simply click on the gutter to the immediate left of the line of code we'd like to
add a breakpoint to. The same red circle should appear in the gutter where you clicked:

MOBILE APPLICATION DEVELOPMENT 187


Hitting Breakpoints:
Then, we can run our code by selecting the "Debug" icon at the top. This will launch our
application in the emulator or connected device.

If an emulator is not already running, this will prompt you to select an emulator or device to run
the application on. Once an emulator is up and running, travel to the activity the breakpoint was
placed in. When the code containing the breakpoint is executed, the application will pause, and the
debugger console will appear in the lower half of the Android Studio window:

Using the Android Debugger:


Once the application is paused, we have several options. We can hover over variables to see their
current values:

If we click the + symbol on the left side of the yellow pop-over that appears when we hover over a
variable, we can see further details, too:

MOBILE APPLICATION DEVELOPMENT 188


Navigating Through Code:
Additionally, the Debugger pane will open in the lower half of the Android Studio window. The
debugger contains multiple buttons for interacting with code. Here are the 10 you'll use the most:

1. Show Execution Point: This will place the cursor back to the spot you're currently debugging.
(ie: if you insert a breakpoint somewhere, look around in a few other files, you can hit this to
return to your original breakpoint).
2. Step Over: this advance to the next line of code without entering a method.
3. Step Into: This will advance to the first line of code inside a method call.
4. Force Step Into: This will forcibly advance to the first line of code inside a method call, if the
option above does not work for any reason.
5. Step Out: This advances to the next line of code outside of the current method.
6. Resume Program: This will continue running the app normally.
7. Pause Program: This will be greyed-out at first, because the program is already paused. If you
opt to resume the program, you may pause it again with this option.
8. Stop App: This halts the running application in the emulator or device entirely.
9. View Breakpoints: This will open a window that will summarize exactly which breakpoints
have been inserted into what areas of your application. In addition, it will allow you to customize
settings for each individual breakpoints. For instance, you can select Remove once hit to
automatically remove the breakpoint after it pauses your code. Log message to console to include
a message in the logcat when this breakpoint is hit, or add conditions, log messages, and filters.

MOBILE APPLICATION DEVELOPMENT 189


10. Mute Breakpoints: This is an option you can toggle on and off that will temporarily ignore
other breakpoints in the code while you interact with the code in other ways (primarily stepping
into/out of/through/etc.)
Dalvik Debug Monitor Service (DDMS):
The DDMS is a powerful debugging tool that is downloaded as part of the Android
SDK. DDMS can be run either by selecting the DDMS icon on the top-right corner of the Eclipse
IDE or by selecting the Window, Open Perspective, DDMS option.
When we run DDMS, it automatically connects to the attached Android device or any running
emulator. DDMS helps with a variety of tasks, including
• Finding bugs in applications running either on an emulator or on the physical device.
• Providing several services such as port forwarding, on-device screen capture, incoming call,
SMS, and location data spoofing.
• Showing the status of active processes, viewing the stack and heap, viewing the status of active
threads, and exploring the file system of any active emulator.
• Providing the logs generated by LogCat, so we can see log messages about the state of the
application and the device. LogCat displays the line number on which the error(s) occurred.
• Simulating different types of networks, such as GPRS and EDGE.

Figure 5.11. The DDMS tool window

MOBILE APPLICATION DEVELOPMENT 190


In the upper-left pane of the DDMS window, we see a Devices tab that displays the list of
Android devices connected to your PC, along with the running AVDs (if any). The VMs
associated with each device or AVD also is displayed. Selecting a VM displays its information in
the right pane. In the Devices tab, you see some icons, described here:
• Debug—Used to debug the selected process.
• Update Heap—Enables heap information of the process. After clicking this icon, use
the Heap icon on the right pane to get heap information.
• Dump HPROF file—Shows the HPROF file that can be used for detecting memory leaks.
• Cause GC—Invokes Garbage Collection.
• Update Threads—Enables fetching the thread information of the selected process. After
clicking this icon, we need to click the Threads icon in the right pane to display information about
the threads that are created and destroyed in the selected process.
• Start Method Profiling—Used to find the number of times different methods are called in an
application and the time consumed in each of them. Click the Start Method Profiling icon, interact
with the application, and click the Stop Method Profiling icon to obtain information related to the
different methods called in the application.
• Stop Process—Stops the selected process.
• Screen Capture—Captures our device/emulator screen. If the application is running and its
output is being displayed through the device/emulator, clicking the Screen Capture icon displays
the Device Screen Capture dialog box, as shown in Figure 5.12 (left). The text, Capturing, tells us
that the output of the application or image being displayed in the device/emulator is in the process
of being captured. Once the image is captured, it is displayed as shown in Figure 5.12 (right).

Figure 5.12. Image shown in the device/emulator is being captured (left), and the captured
image of the device/emulator displayed (right)
The meaning of the buttons shown at the top in the Device Screen Capture dialog box is shown
here:
• Refresh—Updates the captured image.
• Rotate—With each click of this button, the captured image rotates 90 degrees in the
counterclockwise direction.
• Save—Saves the captured image as a .png file.
• Copy—Copies the captured image to the clipboard.
MOBILE APPLICATION DEVELOPMENT 191
• Done—Closes the Device Screen Capture dialog.
Back to DDMS, on the right pane (refer to Figure 5.11), we find the following tabs:
• Threads—Displays information about the threads within each process, as shown in Figure
5.13 (left). The following information about the threads is displayed:
• Thread ID—Displays the unique ID assigned to each thread
• Status—Displays the current status of the thread—whether it is in running, sleeping, starting,
waiting, native, monitor, or zombie state
• utime—Indicates the cumulative time spent executing user code
• stime—Indicates the cumulative time spent executing system code
• Name—Displays the name of the thread
• Heap—Displays the heap information of the process (provided the Update Heap button from
the Devices tab has been clicked). Select the Cause GC button to begin the garbage collection
process. The object types and the size of memory allocated to them are displayed. After we select
an object type, a bar graph is displayed, showing the number of objects allocated for a particular
memory size in bytes (see Figure 5.13—right).

Figure 5.13. The Threads tab, displaying information about running threads (left), and
the Heap tab displaying heap information of the current process (right)
• Allocation Tracker—Tracks the objects allocated to an application. Click the Start
Trackingbutton, interact with the application, and then click Get Allocations to see the list of
objects allocated to the application (see Figure 5.14—left). After we click the Get
Allocations button again, the newly allocated objects are added to the earlier displayed list of
allocated objects. We can also click the Stop Tracking button to clear the data and restart.

MOBILE APPLICATION DEVELOPMENT 192


Figure 5.14. The Allocation Tracker tab, which tracks objects allocated to the application
(left) and the File Explorer tab, displaying the file system on the device/emulator (right)
• Network Statistics—Helps us in getting information regarding network usage of our
application, that is, when our app made network requests, speed of data transfer—and other
related information.
• File Explorer—Displays the file system on the device, as shown in Figure 5.14 (right). We can
view and delete files on the device/emulator through this tab. We can even push or pull files from
the device using the two icons, Pull a file from the device and Push a file onto the device, that are
shown at the top. To copy a file from the device, select the file in the File Explorer and click
the Pull a file from the device button. The Get Device File dialog box opens up, prompting us to
specify the path and filename where we want to store the pulled device file. Similarly, to copy a
file to the device, click the Push file onto the device button in the File Explorer tab. The Put File
on Device dialog box opens up, letting us browse the local disk drive. Select the file we want to
copy to the device and click Open button to copy it to the device.
Right of the File Explorer tab is the Emulator Control tab that can be used to simulate incoming
phone calls, SMS messages, or GPS coordinates.

Figure 5.15. Simulating an incoming phone call through the Emulator Control tab (left), and
an incoming phone call appears on the Android emulator (right).
MOBILE APPLICATION DEVELOPMENT 193
To simulate an SMS message, select the SMS option in the Emulator Control tab, provide the
phone number, write the message, and click the Send button, as shown in Figure 5.16 (left). In the
emulator, an incoming SMS notification appears at the top (see Figure 5.16—right). We can
simulate GPS coordinates (longitude and latitude values) manually, via the GPX file or KML file
through the Emulator Control tab. Remember, only GPX 1.1 files are supported.

Figure 5.16. Simulating SMS via the Emulator Control tab (left), and incoming SMS
notification displayed at the top in the Android emulator (right)
The bottom pane of the DDMS is used to show the log of the processes on the selected device or
AVD. The pane is meant for performing debugging and tracing tasks. The LogCat tab shows all
messages of the device, including exceptions and those placed in the application to see the
intermediate results. We can also set up filters to watch filtered log information. The Console tab
displays the messages related to the starting of the activity.
Let‘s move ahead and examine the most critical and essential task in software development—
debugging.
Debugging Applications:
The two most common ways of debugging an application and finding out what went wrong are
placing breakpoints and displaying log messages.
Placing Breakpoints in an Application
Breakpoints are used to temporarily pause the execution of the application, allowing us to
examine the content of variables and objects. To place a breakpoint in an application, select the
line of code where you want to place a breakpoint and either press Ctrl+Shift+B,
select Run, Toggle Breakpoint, or double-click in the marker bar to the left of the line in the
Eclipse code editor. You can place as many breakpoints as you want in our application. Let‘s
return to the Android project, HelloWorldApp, that we created in Chapter 1, ―Introduction to
Android.‖ Add a few statements to its activity file, as shown in Listing 5.22. The statements just
perform simple multiplication and display log messages. Only the statements in bold are newly
added; the rest of the code is the same as the code in Listing 1.5.
Listing 5.22. Code Added to the Java Activity File HelloWorldAppActivity.java
package com.androidunleashed.helloworldapp;

import android.app.Activity;
import android.os.Bundle;

MOBILE APPLICATION DEVELOPMENT 194


import android.widget.TextView;
import android.util.Log;

public class HelloWorldAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello_world_app);
TextView mesg = (TextView)findViewById(R.id.message);
mesg.setText("Hello World!");
int a,b,c;
a=10;
b=5;
c=a*b;
Log.v("CheckValue1", "a = " + a);
Log.v("CheckValue2", "b = " + b);
Log.v("CheckValue3", "c = " + c);
Log.i("InfoTag", "Program is working correctly up till here");
Log.e("ErrorTag", "Error--Some error has occurred here");
}
}
Let‘s place breakpoints at the following three statements in the activity file:
c=a*b;
Log.v("CheckValue1", "a = " + a);
Log.v("CheckValue3", "c = " + c);
When we place these breakpoints, a blue dot appears on the left, indicating that the breakpoints
were successfully inserted (see Figure 5.17).

Figure 5.17. Activity file displaying the statements where breakpoints are inserted

MOBILE APPLICATION DEVELOPMENT 195


To stop execution at the breakpoints, don‘t run the application; instead debug it by either
pressing F11, selecting Run, Debug, or right-clicking the project in Package Explorer and
selecting Debug As, Android Application. During debugging, the application pauses when the
first breakpoint is reached. At the breakpoints, we can highlight variables to see their values and
execute certain expressions. When the application reaches a breakpoint for the first time, a
window pops up asking whether we want to switch to the Debug perspective, as shown in Figure
5.18. To prevent this window from appearing again, check the Remember my decision check box
and click Yes.

Figure 5.18. Dialog prompting to switch to the Debug perspective

Using the Debug Perspective:


When the application switches from the Java to the Debug perspective, you see the callback stack,
console, code view, and variables, as shown in Figure 5.19.

Figure 5.19. The Debug perspective window showing different panes

MOBILE APPLICATION DEVELOPMENT 196


The following panes are visible by default in Debug perspective:
• Debug—On the top left, this pane displays the application being debugged, along with its
currently running threads.
• Variables—Displays values of the variables at the specific breakpoints.
• Breakpoints—Lists all the breakpoints inserted in the code.
• Editor—At the middle left, this pane displays the application code pointing to the breakpoint
where the application is currently suspended.
• Outline—At the center right, this pane lists the imports, classes, methods, and variables used in
the application. When we select an item in the Outline pane, the matching source code in
the Editorpane is highlighted.
• Console—At the bottom left, the pane displays the status of emulator/device activity, such as the
launching of activities.
• LogCat—At the bottom right, this pane displays the system log messages.
Debug Pane
The Debug pane displays debug session information in a tree hierarchy. In Figure 5.19, you notice
that in the Debug pane the call stack starts with a line, Thread [<1> main] (Suspended (breakpoint
at line 19)), telling us that the application is suspended at the breakpoint on line 19. On selecting
the top stack frame icon (horizontal blue bars), in the Variables window, you see several gray
circles labeled with the variables used in the application and showing their values at the
breakpoint. A call stack is a data structure that keeps the sequence or order of different functions
or subroutines called in an application. It stores the return address of the subroutines that are
called in an application so that when the subroutine is over, the execution resumes from the
statement following where the subroutine was called. The following buttons appear starting from
the left, at the top of this pane:
• Remove All Terminated Launches—Clears all terminated processes from the display.
• Resume (F8)—Resumes execution of the currently suspended debugging session.
• Suspend—Pauses the selected debugging session.
• Terminate (Ctrl+F2)—Ends the selected debugging session.
• Disconnect—Disconnects the debugger from the selected debug target. The disconnected
process can be relaunched by right-clicking it in the Debug pane and selecting
the Relaunch option.
• Step Into (F5)—Executes the current statement or method and proceeds to the next method
call/statement.
• Step Over (F6)—Steps over the next method call/statement. On every Step-Over, we can
examine the values of the variables and output. The value of the variables can be examined in
the Variables pane and the output in the Console pane. To see the value of any variable, hover
over it with the mouse and its content is displayed.
• Step Return (F7)—Returns from the method that has been stepped into.
• Drop To Frame—Used to rerun a part of an application. Select a stack frame in the call stack
and select this option to rerun the application from there.
• Use Step Filters—Ensures that all step functions apply step filters. The step filters are used to
filter out the classes that we don‘t want to step into. To specify the classes that we want to filter
out while stepping, select Window, Preferences. In the Preferences window that opens, navigate
to Java, Debug, Step Filtering. We see the list of packages and classes and can select the ones we
want to be filtered out (see Figure 5.20).

MOBILE APPLICATION DEVELOPMENT 197


Figure 5.20. Dialog box for applying and managing step filters
After selecting the classes/packages to be filtered out, click OK to close the Preferences window.
The selected classes/packages are filtered while stepping through the code, provided the Use Step
Filters toggle button in the Debug view is On.
The Debug pane also displays a Debug view menu to perform tasks, such as changing the layout
of debug view (tree, breadcrumb, and so on), controlling view management, and activating or
deactivating the child elements shown in the Debug pane.
Expressions Pane
We can also open an Expressions pane that we can use to compute expressions with different
variables of the application. The Expressions pane is not visible by default. To open it,
select Window, Show View, Expressions. The Expressions pane appears, as shown in Figure
5.21 (left). We can add our own expressions by clicking the + Add new expression button shown
in the last row of the Expressions pane. Write the expression in the text entry box.

Figure 5.21. Expressions pane showing the default expression (left), and Expressionspane
with several expressions and their respective values (right)

MOBILE APPLICATION DEVELOPMENT 198


Breakpoints Pane:
The Breakpoints pane displays all the inserted breakpoints in the application, as shown in Figure
5.22. This pane helps in enabling, disabling, skipping, and removing breakpoints. It also helps in
suspending the breakpoint on specific conditions.

Figure 5.22. The Breakpoints pane showing applications breakpoints


At the bottom of the Breakpoints pane, we find two check boxes: Hit count and Conditional.
The Hit count is for specifying the number of times we want the breakpoint to occur before
suspending the thread execution. The Conditional check box is for specifying a condition when
we want to suspend a thread. From the Editor pane, right-click the breakpoint (blue dot) in the
marker bar and select Breakpoint Properties from the context menu that opens. A dialog box
appears, as shown in Figure 5.23.

Figure 5.23. The Breakpoint Properties dialog box


The check boxes are as follows:
• Enabled—This check box is selected by default, indicating the breakpoint is active. When it is
unchecked, the breakpoint is disabled and the breakpoint image, which was a solid blue dot,
becomes a white hollow dot.
• Hit Count—When a breakpoint is applied to a statement within a loop, the application suspends
for the number of times equal to the iteration of the loop. We can select the Hit count check box
and add a numerical value into the text field, for example, 10. In this case, the breakpoint is
ignored 10 times before being suspended again.

MOBILE APPLICATION DEVELOPMENT 199


• Conditional—Used to suspend a breakpoint when a specific condition occurs. To write a
condition, select the Conditional check box and write a Boolean statement in the box below it. For
example, the Boolean statement a >=10 suspends the breakpoint only if the value of the
variable, a, is greater than or equal to 10 (see Figure 5.24—left). To suspend the breakpoint every
time the specified condition evaluates to true, select the Suspend when 'true' radio button.
The Suspend when value changes radio button causes the breakpoint to suspend when the result of
the condition changes. Click OK to apply the conditional breakpoint. A question mark (?) appears
on the breakpoint in the Breakpoints pane to which the condition is applied, as shown in Figure
5.24 (right).

Figure 5.24. Applying a condition for suspending a breakpoint (left) and a question mark (?)
displayed on the conditional (right)
The following buttons appear at the top of the Breakpoints pane, from left to right:
• Remove Selected Breakpoints—Removes the selected breakpoint. You can also remove a
breakpoint from the Editor pane by double-clicking on the blue dot that represents the breakpoint
in the marker bar. You also can right-click on the blue dot and select Toggle Breakpoint from the
context menu that opens.
• Remove All Breakpoints—Removes all breakpoints from the application.
• Show Breakpoints Supported by Selected Target—Displays the breakpoints that are
supported by the currently selected debug target.
• Go to File for Breakpoint—Highlights the statement in the Editor pane where the breakpoint is
suspended.
• Skip All Breakpoints—Ignores all breakpoints.
• Expand All—Expands all the collapsed elements in the view.
• Collapse All—Collapses all the expanded elements in the view.
• Link with Debug View—Highlights the selected breakpoint when the application moves from
one breakpoint to another in the Debug view.
• Add a Java Exception Breakpoint—Lets you set breakpoints that are suspended when
exceptions are thrown. A thread can be suspended when the specified exception occurs, whether it
is uncaught, caught, or both. To understand this concept, we need to add some statements, shown
in Listing 5.23, to the HelloWorldApp application activity file that throws an exception. Only the
statements in bold are newly added code; the remainder is the same as the code in Listing 5.22.
Listing 5.23. Code Added to the Java Activity File HelloWorldAppActivity.java
MOBILE APPLICATION DEVELOPMENT 200
package com.androidunleashed.helloworldapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.util.Log;
public class HelloWorldAppActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello_world_app);
TextView mesg = (TextView)findViewById(R.id.message);
mesg.setText("Hello World!");
int a,b,c;
a=10;
b=5;
c=a*b;
callExcep();
Log.v("CheckValue1", "a = " + a);
Log.v("CheckValue2", "b = " + b);
Log.v("CheckValue3", "c = " + c);
Log.i("InfoTag", "Program is working correctly up till here");
Log.e("ErrorTag", "Error--Some error has occurred here");
}
public void callExcep() {
throw new RuntimeException("RuntimeException testing");
}
}
We see that a method, callExcep(), that throws a RuntimeException is defined. When we don‘t
insert Java Exception Breakpoint, if the application is run, it simply crashes when the exception is
thrown. To suspend the thread execution when the exception occurs, select the Add a Java
Exception Breakpoint button from the Breakpoints pane.

Figure 5.25. Dialog box for adding a Java Exception Breakpoint (left), and
the Breakpoints pane showing the RuntimeException (right)

MOBILE APPLICATION DEVELOPMENT 201


Type the name of the exception you want to catch or select it from the list. Two check boxes are
displayed at the bottom so you can choose whether you want to suspend the thread execution
on caught or uncaught exceptions. Select Suspend on caught exceptions to suspend the thread
execution at locations where the exception is thrown and is caught by a catch clause. Similarly,
select Suspend on uncaught exception if you want to suspend thread execution at locations where
the exception is thrown but is uncaught. Let‘s select RuntimeException from the list of available
exceptions. Keep the two check boxes selected (by default) and select OK to add an Exception
Breakpoint to the application. An exception, RuntimeException caught and uncaught, is added
and displayed in the Breakpoints pane, as shown in Figure 5.25 (right). Now the thread is
suspended on the statement that throws the exception, allowing us to examine the variables and
the LogCat logging pane to see what went wrong.
Variables Pane
The Variables pane displays values of the variables associated with the stack frame selected in
the Debug pane, as shown in Figure 5.26 (left). As we step into the application, new variables may
be added and the values of the existing variables display their current value, as shown in Figure
5.26(right). To see the values of the variables up to a particular statement, you can place the cursor
on a particular statement in the Editor pane and select Run-To-Line from the Run menu or
press Ctrl+R to continue execution up to the selected statement.

Figure 5.26. The Variables pane showing the values of the variables at a stack frame (left),
and the Variables pane displaying variable values after stepping all the breakpoints (right)
Adding Logging Support to Android Applications
LogCat is commonly used for debugging an application. This utility is provided through
the Log class of the android.util package and displays the log messages, exceptions,
warnings, System.out.println, and intermediate results that occur during runtime. The methods in
the android.util.Log class are shown in Table 5.2.
Table 5.2. Methods Used in the Log Class

These methods display log messages of different severity levels. To add logging support to our
application, add the following import statement to the Activity file for the Log class:
import android.util.Log;

MOBILE APPLICATION DEVELOPMENT 202


The logging messages need to be tagged as follows:
Log.i("debug_tag", "Message to display");
Examples:
Log.i("InfoTag", "Program is working correctly up till here");
Log.e("ErrorTag", "Error--Some error has occurred here");
In these examples, we‘re logging an Info message and then an Error message, which shows up
in Logcat in green and red, respectively. To keep the tags consistent, it is better to create static
final String constants, as shown in the following statements:
private static final String INFO_TAG = "InfoTag";
Log.i(INFO_TAG, "a = " + a);
Log.i(INFO_TAG, "This is info tag ");
We can see that the two logging messages are assigned a consistent tag, INFO_TAG. This
consistency in tags helps in filtering out the desired log messages. By default, the LogCat pane
shows log messages related to the entire application, as shown in Figure 5.27.

Figure 5.27. LogCat showing all the log messages of the application
To see only the desired log messages, we can set up a filter by clicking the green plus sign in
the LogCat pane. We see a dialog box, Logcat Message Filter Settings, as shown in Figure
5.28(left). Here we have to specify the Filter Name, the Log Tag whose messages we want to see,
the application name if we want to see log messages related to the entire application, and Log
Levelto filter the log messages on the basis of severity level.

Figure 5.28. Dialog box for adding Log Cat filters (left), and filtered log messages displayed
after selecting the filter (right)
Let‘s specify the filter name as check filter and Log Tag as CheckValue1, as we wish to see the
log messages related to this tag only. Specify the application name as com .android unleashed.
Hello world app to focus only on the application‘s logs.
MOBILE APPLICATION DEVELOPMENT 203
Displaying and Fetching Information Using Dialogs and Fragments:
A smaller window that pops up to interact with the user. It can display important messages and
can even prompt for some data. Once the interaction with the dialog is over, the dialog disappears,
allowing the user to continue with the application. Fragments, as the name suggests, enable us to
fragment or divide our Activities into encapsulated reusable modules, each with its own user
interface, making our application suitable to different screen sizes. That is, depending on the
available screen size, we can add or remove fragments in our application.
What Are Dialogs?
Create a new activity or screen for interacting with users, but when we want only a little
information, or want to display an essential message, dialogs are preferred. Dialogs are also used
to guide users in providing requested information, confirming certain actions, and displaying
warnings or error messages. The following is an outline of different dialog window types provided
by the Android SDK:
• Dialog—The basic class for all dialog types.
• AlertDialog—A dialog with one, two, or three Button controls.
• CharacterPickerDialog—A dialog that enables you to select an accented character associated
with a regular character source.
• DatePickerDialog—A dialog that enables you to set and select a date with a DatePicker control.
• ProgressDialog—A dialog that displays a ProgressBar control showing the progress of a
designated operation.
• TimePickerDialog—A dialog that enables you to set and select a time with
a TimePicker control.
A dialog is created by creating an instance of the Dialog class. The Dialog class creates a dialog in
the form of a floating window containing messages and controls for user interaction. In Android,
the dialogs are called asynchronously; that is, the dialogs are displayed and the main thread that
invokes the dialogs returns and continues executing the rest of the application.
Each dialog window is defined within the activity where it will be used. A dialog window can be
created once and displayed several times. It can also be updated dynamically.
The following is a list of the Activity class dialog methods:
• showDialog()—Displays a dialog and creates a dialog if one does not exist. Each dialog has a
special dialog identifier that is passed to this method as a parameter.
• onCreateDialog()—The callback method that executes when the dialog is created for the first
time. It returns the dialog of the specified type.
• onPrepareDialog()—The callback method used for updating a dialog.
• dismissDialog()—Closes the dialog whose dialog identifier is supplied to this method. The
dialog can be displayed again through the showDialog() method.
• removeDialog()—The dismissDialog() method doesn‘t destroy a dialog. The dismissed dialog
can be redisplayed from the cache. If we do not want to display a dialog, we can remove it from
the activity dialog pool by passing its dialog identifier to the removeDialog() method.
All these methods are deprecated, with the new preferred way being to use
the DialogFragment with the FragmentManager (explained later in the chapter). Older platforms
should use the compatibility library to use DialogFragment and the FragmentManager.
The onCreateDialog() method is called only once while creating the dialog for the first time,
whereas the onPrepareDialog() method is called each time the showDialog() method is called,
allowing the activity to update the dialog before displaying it to the user. Basically, instead of
creating new instances of a dialog each time, onCreateDialog() and onPrepareDialog() persist and
MOBILE APPLICATION DEVELOPMENT 204
manage dialog box instances. When these methods persist the state information within dialogs,
any option selected or data entered in any of its text fields will remain and will be lost while
displaying different dialog instances.
By overriding the onCreateDialog method, we specify dialogs that will be created
when showDialog() is called. Several dialog window types are available in the Android SDK,
such as AlertDialog, DatePickerDialog, and TimePickerDialog, that we can readily use in an
application. All the dialog windows are created by extending the Dialog class. Let‘s begin
with AlertDialog.
AlertDialog:
An AlertDialog is a popular method of getting feedback from the user. This pop-up dialog
remains there until closed by the user and hence is used for showing critical messages that need
immediate attention or to get essential feedback before proceeding further.
The simplest way to construct an AlertDialog is to use the static inner
class AlertDialog.Builder that offers a series of methods to configure an AlertDialog. This
example creates a new AlertDialog.Builder object called alertDialog:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
In this example, this refers to the context, that is, the current activity created here. We can add
a title, icon, and message to the alertDialog object that we want to display in the dialog. We can
define buttons and controls for user interaction to display in the dialog. We can also register event
listeners with the dialog buttons for handling events. All these tasks can be easily accomplished
through the methods provided by the AlertDialog.Builder subclass. Let‘s have a quick look at the
methods provided.
Methods of the AlertDialog.Builder Subclass:
The methods of the AlertDialog.Builder subclass that we can use to configure the AlertDialogbox
are
• setTitle() and setIcon()—For specifying the text and icon to appear in the title bar of the dialog
box.
• setMessage()—For displaying a text message in the dialog box.
• setPositiveButton(), setNeutralButton(), and setNegativeButton()—For configuring the
following three buttons:
• Positive button—Represents the OK button.
• Negative button—Represents the Cancel button.
• Neutral button—Represents a button to perform a function other than OK or Cancel.
Through these three methods, we can set the three buttons to appear in the dialog and also define
their location in the dialog box. We can also define the captions and actions of these buttons.
Let‘s create an Android application to see how AlertDialog is displayed. Name the
project AlertDialogApp. In this application, we want to display a Button control that, when
clicked, displays the AlertDialog. So, first we need to define a Button control in the layout
file activity_alert_dialog_app.xml.
The Layout File activity_alert_dialog_app.xml After Adding the ButtonControl
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
MOBILE APPLICATION DEVELOPMENT 205
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/click_btn"
android:text="Click for Alert Dialog" />
</LinearLayout>
To display an AlertDialog, we use the AlertDialog.Builder subclass to create a Builderobject.
Thereafter, we configure the dialog with a title, message, and buttons with the Builder object. We
then define actions for the respective buttons, if any. Finally, the dialog is built and shown on the
screen through the Builder object.
The Java Activity File AlertDialogAppActivity.java
package com.androidunleashed.alertdialogapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.view.View;
import android.app.AlertDialog;
import android.content.DialogInterface;
public class AlertDialogAppActivity extends Activity implements OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alert_dialog_app);
Button b = (Button)this.findViewById(R.id.click_btn);
b.setOnClickListener(this);
}
@Override
public void onClick(View v) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("Alert window");
alertDialog.setIcon(R.drawable.ic_launcher);
alertDialog.setMessage("This is an alert");
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int buttonId) {
return;
}
});
alertDialog.show();
}
}
Here we see that the click_btn Button control in the layout file is assigned the caption Click for
Alert Dialog. The Button control is captured from the layout file and is mapped to
the Buttonobject, b. We want the AlertDialog to appear when the click_btn button is clicked;
hence an event listener, setOnClickListener, is associated with it When click_btn is clicked,
the onClick() callback method is executed. In onClick() a Builder called alertDialog is created. To
display the alert dialog on the screen, we provide the Context—the current activity—to the builder
MOBILE APPLICATION DEVELOPMENT 206
object. We then set the icon and title for the dialog box. The title and text of the dialog are set to
Alert window and This is an alert, respectively. A positive button is configured in the dialog with
the caption OK. In the button‘s click handler, we simply do nothing and return. The AlertDialog is
made visible on the screen through the show() method.
After running the application, we see a Button control with the caption Click for Alert Dialog, as
shown in Figure 6.1 (left). When we select the Button control, an AlertDialog is displayed with
the title Alert window showing the message.

Button with the caption Click for Alert Dialog displayed on application startup (left), and
the AlertDialog appears on selecting the Button control (right)
Besides showing essential or critical messages to the user that require immediate action,
the AlertDialog can also be used for getting input from the user. Let‘s see how.
Selecting the Date and Time in One Application:
The system date and time can be set in an application, let‘s create a new Android application and
name it DateTimePickerApp. In this application, we use a TextView and two Button controls. The
TextView control displays the current system date and time, and the two Button controls, Set Date
and Set Time, are used to invoke the respective dialogs. When the Set Date button is selected, the
DatePickerDialog is invoked, and when the Set Time button is selected, the TimePickerDialog is
invoked.
So, let‘s write the code shown in Listing 6.9 into the layout file
activity_date_time_picker_app.xml to define a TextView and two Button controls.
The Layout File activity_date_time_picker_app.xml After Adding the TextView and Button
controls
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView android:id="@+id/datetimevw"

MOBILE APPLICATION DEVELOPMENT 207


android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button android:id="@+id/date_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set Date" />
<Button android:id="@+id/time_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set Time" />
</LinearLayout>
We can see here that the TextView and the two Button controls are defined with the
IDs datetimevw, date_button, and time_button, respectively. The captions for the
two Buttoncontrols are Set Date and Set Time, respectively.
After defining the controls in the layout file, we write Java code into
the DateTimePickerAppActivity.java activity file to perform the following tasks:
• Display the current system date and time in the TextView control.
• Invoke DatePickerDialog and TimePickerDialog when the Set Date and Set Time
Button controls are clicked.
• Initialize DatePickerDialog and TimePickerDialog to display the current system date and time
via the Calendar instance.
• Display the modified date and time set by the user via
the DatePickerDialog and TimePickerDialog through the TextView control.
The Java Activity File DateTimePickerAppActivity.java
package com.androidunleashed.datetimepickerapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Button;
import java.util.Calendar;
import android.app.TimePickerDialog;
import android.app.DatePickerDialog;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.TimePicker;
import android.widget.DatePicker;

public class DateTimePickerAppActivity extends Activity {


private TextView dateTimeView;
private Calendar c;
private int h, m,yr,mon,dy;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_date_time_picker_app);
dateTimeView = (TextView) findViewById(R.id.datetimevw);
MOBILE APPLICATION DEVELOPMENT 208
Button timeButton = (Button) findViewById(R.id.time_button);
Button dateButton = (Button) findViewById(R.id.date_button);
c = Calendar.getInstance();
h = c.get(Calendar.HOUR_OF_DAY);
m = c.get(Calendar.MINUTE);
yr = c.get(Calendar.YEAR);
mon = c.get(Calendar.MONTH);
dy = c.get(Calendar.DAY_OF_MONTH);
dateTimeView.setText("Current date is "+ (mon+1)+"-"+dy+"-"+yr+" and current
time is: "+h+":"+m);
dateButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new DatePickerDialog(DateTimePickerAppActivity.this, dateListener,
yr, mon, dy).show();
}
});
timeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new TimePickerDialog(DateTimePickerAppActivity.this, timeListener,
h,m,true).show();
}
});
}

private DatePickerDialog.OnDateSetListener dateListener = new DatePickerDialog.


OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOf-
Month)
{
yr = year;
mon = monthOfYear;
dy = dayOfMonth;
dateTimeView.setText("Current date is "+ (mon+1)+"-"+dy+"-"+yr+" and
current time is: "+h+":"+m);
}
};
private TimePickerDialog.OnTimeSetListener timeListener = new TimePickerDialog.
OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hour, int minute) {
h = hour;
m = minute;
dateTimeView.setText("Current date is "+ (mon+1)+"-"+dy+"-"+yr+" and
current time is: "+h+":"+m);
}
};
}

MOBILE APPLICATION DEVELOPMENT 209


The respective listeners, OnDateSetListener and OnTimeSetListener, invoke their callback
methods, onDateSet() and onTimeSet(), when the Done button in the DatePickerDialog or
TimePickerDialog is selected by the user. The two callback methods access the newly set date and
time and display them through the TextView control. After we run the application, the system‘s
current date and time are displayed through the TextViewcontrol. Two Button controls with the
captions Set Date and Set Time are displayed. When the Set Date button is clicked, the
DatePickerDialog showing the system‘s current date is displayed (middle). If we scroll in an up or
down direction, the day, month, and year can be changed as desired. After we set the desired date,
the currently set date and time are displayed via the TextView control.

The TextView displaying the current date and time and two Buttoncontrols (left), the
DatePicker dialog appears when the Set Date button is clicked (middle), and the date
selected from the DatePicker dialog displayed in the TextView(right)
Similarly, when the Set Time button is clicked, the TimePickerDialog initialized to the system‘s
current time is displayed. If we scroll in an up or down direction, the hour and minute can be
changed as desired. After we set the desired time in the TimePickerDialog, the currently set date
and time are displayed via the TextView control.

MOBILE APPLICATION DEVELOPMENT 210


The TimePicker dialog appears when the Set Time button is clicked (left), changing the hour
and minutes in the TimePicker dialog (middle), and the time selected from
the TimePicker dialog displayed in the TextView (right)
We can also format the date and time. Let‘s modify the DateTimePicker AppActivity.java file
The Java Activity File DateTimePickerAppActivity.java
package com.androidunleashed.datetimepickerapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Button;
import java.util.Calendar;
import android.app.TimePickerDialog;
import android.app.DatePickerDialog;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.TimePicker;
import android.widget.DatePicker;
import java.text.DateFormat;
public class DateTimePickerAppActivity extends Activity {
private TextView dateTimeView;
private Calendar c;
DateFormat DateTimeFormat = DateFormat.getDateTimeInstance();

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_date_time_picker_app);
dateTimeView = (TextView) findViewById(R.id.datetimevw);
Button timeButton = (Button) findViewById(R.id.time_button);
Button dateButton = (Button) findViewById(R.id.date_button);
c = Calendar.getInstance();
dateTimeView.setText(DateTimeFormat.format(c.getTime()));
dateButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new DatePickerDialog(DateTimePickerAppActivity.this, dateListener,c.
get(Calendar.YEAR), c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH)).show();
}
});
timeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new TimePickerDialog(DateTimePickerAppActivity.this, timeListener,
c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),true).show();
}
});

MOBILE APPLICATION DEVELOPMENT 211


}

private DatePickerDialog.OnDateSetListener dateListener = new DatePickerDialog.


OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOf-
Month)
{
c.set(Calendar.YEAR,year);
c.set(Calendar.MONTH,monthOfYear);
c.set(Calendar.DAY_OF_MONTH,dayOfMonth);
dateTimeView.setText(DateTimeFormat.format(c.getTime()));
}
};

private TimePickerDialog.OnTimeSetListener timeListener = new


TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hour, int minute) {
c.set(Calendar.HOUR_OF_DAY, hour);
c.set(Calendar.MINUTE, minute);
dateTimeView.setText(DateTimeFormat.format(c.getTime()));
}
};
}
After we run the application, the formatted date and time are displayed.

Formatted date and time

MOBILE APPLICATION DEVELOPMENT 212


Fragments:
A Fragment is a piece of an activity which enable more modular activity design. It will not be
wrong if we say, a fragment is a kind of sub-activity.
Following are important points about fragment −
 A fragment has its own layout and its own behaviour with its own life cycle callbacks.
 You can add or remove fragments in an activity while the activity is running.
 You can combine multiple fragments in a single activity to build a multi-pane UI.
 A fragment can be used in multiple activities.
 Fragment life cycle is closely related to the life cycle of its host activity which means
when the activity is paused, all the fragments available in the activity will also be stopped.
 A fragment can implement a behavior that has no user interface component.
 Fragments were added to the Android API in Honeycomb version of Android which API
version 11.
Create fragments by extending Fragment class and you can insert a fragment into your activity
layout by declaring the fragment in the activity's layout file, as a <fragment> element.
Prior to fragment introduction, we had a limitation because we can show only a single activity on
the screen at one given point in time. So we were not able to divide device screen and control
different parts separately. But with the introduction of fragment we got more flexibility and
removed the limitation of having a single activity on the screen at a time. Now we can have a
single activity but each activity can comprise of multiple fragments which will have their own
layout, events and complete life cycle.
Following is a typical example of how two UI modules defined by fragments can be combined
into one activity for a tablet design, but separated for a handset design.

The application can embed two fragments in Activity A, when running on a tablet-sized device.
However, on a handset-sized screen, there's not enough room for both fragments, so Activity A
includes only the fragment for the list of articles, and when the user selects an article, it starts
Activity B, which includes the second fragment to read the article.
Fragment Life Cycle:
Android fragments have their own life cycle very similar to an android activity. This section briefs
different stages of its life cycle.

MOBILE APPLICATION DEVELOPMENT 213


Fragment Lifecycle
The list of methods which you can to override in your fragment class −
 onAttach()The fragment instance is associated with an activity instance.The fragment and
the activity is not fully initialized. Typically you get in this method a reference to the
activity which uses the fragment for further initialization work.
 onCreate() The system calls this method when creating the fragment. You should
initialize essential components of the fragment that you want to retain when the fragment
is paused or stopped, then resumed.
 onCreateView() The system calls this callback when it's time for the fragment to draw its
user interface for the first time. To draw a UI for your fragment, you must return
a View component from this method that is the root of your fragment's layout. You can
return null if the fragment does not provide a UI.
 onActivityCreated()The onActivityCreated() is called after the onCreateView() method
when the host activity is created. Activity and fragment instance have been created as well
as the view hierarchy of the activity. At this point, view can be accessed with the
findViewById() method. example. In this method you can instantiate objects which require
a Context object
 onStart()The onStart() method is called once the fragment gets visible.
 onResume()Fragment becomes active.
 onPause() The system calls this method as the first indication that the user is leaving the
fragment. This is usually where you should commit any changes that should be persisted
beyond the current user session.
 onStop()Fragment going to be stopped by calling onStop()
 onDestroyView()Fragment view will destroy after call this method
 onDestroy()onDestroy() called to do final clean up of the fragment's state but Not
guaranteed to be called by the Android platform.
Types of Fragments:
Basically fragments are divided as three stages as shown below.
 Single frame fragments − Single frame fragments are using for hand hold devices like
mobiles, here we can show only one fragment as a view.
 List fragments − fragments having special list view is called as list fragment
 Fragments transaction − Using with fragment transaction. we can move one fragment to
another fragment.

MOBILE APPLICATION DEVELOPMENT 214


Creating Fragments with java Code:
For creating a Fragment firstly we extend the Fragment class, then override key lifecycle methods
to insert our app logic, similar to the way we would with an Activity class. While creating a
Fragment we must use onCreateView() callback to define the layout and in order to run a
Fragment.
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
public class FirstFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false);
}
}
Here the inflater parameter is a LayoutInflater used to inflate the layout, container parameter is
the parent ViewGroup (from the activity‘s layout) in which our Fragment layout will be inserted.
The savedInstanceState parameter is a Bundle that provides data about the previous instance of the
Fragment. The inflate() method has three arguments first one is the resource layout which we want
to inflate, second is the ViewGroup to be the parent of the inflated layout. Passing the container is
important in order for the system to apply layout parameters to the root view of the inflated
layout, specified by the parent view in which it‘s going and the third parameter is a boolean value
indicating whether the inflated layout should be attached to the ViewGroup (the second
parameter) during inflation.

Implementation of Fragment In Android Require Honeycomb (3.0) or Later:


Fragments were added in in Honeycomb version of Android i.e API version 11. There are some
primary classes related to Fragment‘s are:
1. FragmentActivity: The base class for all activities using compatibility based Fragment (and
loader) features.
2. Fragment: The base class for all Fragment definitions
3. FragmentManager: The class for interacting with Fragment objects inside an activity
4. FragmentTransaction: The class for performing an atomic set of Fragment operations such as
Replace or Add a Fragment.
Example 1:
Below is the example of Fragment‘s. In this example we create two Fragments and load them on
the click of Button‘s. We display two Button‘s and a FrameLayout in our Activity and perform
setOnClickListener event on both Button‘s. On the click of First Button we replace the First
Fragment and on click of Second Button we replace the Second Fragment with the
layout(FrameLayout). In the both Fragment‘s we display a TextView and a Button and onclick of
Button we display the name of the Fragment with the help of Toast.

MOBILE APPLICATION DEVELOPMENT 215


Step 1: Create a new project and name it FragmentExample
Step 2: Open res -> layout ->activity_main.xml (or) main.xml and add following code:
<LinearLayout 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"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<!-- display two Button's and a FrameLayout to replace the Fragment's -->
<Button
android:id="@+id/firstFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/button_background_color"
android:text="First Fragment"
android:textColor="@color/white"
android:textSize="20sp" />

<Button
android:id="@+id/secondFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@color/button_background_color"
android:text="Second Fragment"
android:textColor="@color/white"
android:textSize="20sp" />

MOBILE APPLICATION DEVELOPMENT 216


<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp" />
</LinearLayout>
Step 3: Open src -> package -> MainActivity.java
In this step we open MainActivity and add the code for initiate the Button‘s. After that we
perform setOnClickListener event on both Button‘s. On the click of First Button we replace the
First Fragment and on click of Second Button we replace the Second Fragment with the
layout(FrameLayout). For replacing a Fragment with FrameLayout firstly we create a Fragment
Manager and then begin the transaction using Fragment Transaction and finally replace the
Fragment with the layout i.e FrameLayout.
package com.abhiandroid.fragmentexample;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Button firstFragment, secondFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get the reference of Button's
firstFragment = (Button) findViewById(R.id.firstFragment);
secondFragment = (Button) findViewById(R.id.secondFragment);
// perform setOnClickListener event on First Button
firstFragment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// load First Fragment
loadFragment(new FirstFragment());
}
});
// perform setOnClickListener event on Second Button
secondFragment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// load Second Fragment
loadFragment(new SecondFragment());
}

MOBILE APPLICATION DEVELOPMENT 217


});
}
private void loadFragment(Fragment fragment) {
// create a FragmentManager
FragmentManager fm = getFragmentManager();
// create a FragmentTransaction to begin the transaction and replace the Fragment
FragmentTransaction fragmentTransaction = fm.beginTransaction();
// replace the FrameLayout with new Fragment
fragmentTransaction.replace(R.id.frameLayout, fragment);
fragmentTransaction.commit(); // save the changes
}
}
Step 4: Now we need 2 fragments and 2 xml layouts. So create two fragments by right click on
your package folder and create classes and name them as FirstFragment and SecondFragment and
add the following code respectively.
First Fragment. Class
In this Fragment firstly we inflate the layout and get the reference of Button. After that we
perform setOnClickListener event on Button so whenever a user click on the button a message
―First Fragment― is displayed on the screen by using a Toast.
package com.abhiandroid.fragmentexample;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
public class FirstFragment extends Fragment {
View view;
Button firstButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_first, container, false);
// get the reference of Button
firstButton = (Button) view.findViewById(R.id.firstButton);
// perform setOnClickListener on first Button
firstButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// display a message by using a Toast
Toast.makeText(getActivity(), "First Fragment", Toast.LENGTH_LONG).show();
}
});
MOBILE APPLICATION DEVELOPMENT 218
return view;
}
}
SecondFragment.class
In this Fragment firstly we inflate the layout and get the reference of Button. After that we
perform setOnClickListener event on Button so whenever a user click on the button a message
―Second Fragment― is displayed on the screen by using a Toast.
package com.abhiandroid.fragmentexample;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
public class SecondFragment extends Fragment {
View view;
Button secondButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_second, container, false);
// get the reference of Button
secondButton = (Button) view.findViewById(R.id.secondButton);
// perform setOnClickListener on second Button
secondButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// display a message by using a Toast
Toast.makeText(getActivity(), "Second Fragment", Toast.LENGTH_LONG).show();
}
});
return view;
}
}
Step 5: Now create 2 xml layouts by right clicking on res/layout -> New -> Layout
Resource File and name them as fragment_first and fragment_second and add the following code
in respective files.
Here we will design the basic simple UI by using TextView and Button in both xml‘s.
fragment_first.xml:
<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"
MOBILE APPLICATION DEVELOPMENT 219
tools:context="com.abhiandroid.fragmentexample.FirstFragment">
<!--TextView and Button displayed in First Fragment -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="This is First Fragment"
android:textColor="@color/black"
android:textSize="25sp" />
<Button
android:id="@+id/firstButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@color/green"
android:text="First Fragment"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
fragment_second.xml
<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"
tools:context="com.abhiandroid.fragmentexample.SecondFragment">
<!--TextView and Button displayed in Second Fragment -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="This is Second Fragment"
android:textColor="@color/black"
android:textSize="25sp" />

<Button
android:id="@+id/secondButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
MOBILE APPLICATION DEVELOPMENT 220
android:background="@color/green"
android:text="Second Fragment"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />

</RelativeLayout>
Step 6: Open res ->values ->colors.xml
In this step we define the color‘s that used in our xml file.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- color's used in our project -->
<color name="black">#000</color>
<color name="green">#0f0</color>
<color name="white">#fff</color>
<color name="button_background_color">#925</color>
</resources>
Step 7: Open AndroidManifest.xml
In this step we show the Android Manifest file in which do nothing because we need only one
Activitty i.e MainActivity which is already defined in it. In our project we create two Fragment‘s
but we don‘t need to define the Fragment‘s in manifest because Fragment is a part of an Activity.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.abhiandroid.fragmentexample" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />


</intent-filter>
</activity>
</application>
</manifest>
Step 8: Now run the App and you will two button. Clicking on first button shows First Fragment
and on click of Second Button shows the Second Fragment which is actually
replacing layout(FrameLayout).

MOBILE APPLICATION DEVELOPMENT 221


Creating Special Fragments:
We create a simple Fragment and display it in our Activity by declaring a <fragment> element in
our xml file. We also display a Button in our activity‘s xml and perform click event so whenever a
user click on it a message is displayed on the screen by using a Toast. In the Fragment we display
a TextView and a Button and perform click event of Button so whenever a user click on the
Button a message is displayed on the screen with the help of Toast.
Step 1: Create a new project and name it Fragment Example
Step 2: Open res -> layout ->activity_main.xml (or) main.xml and add following code:
<LinearLayout 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"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<!-- display a Button and a Fragment -->
<Button
android:id="@+id/activity_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@color/button_background_color"
android:text="Activity's Button"
android:textColor="@color/white"
android:textSize="20sp" />
<fragment
android:id="@+id/fragments"
android:name="com.abhiandroid.fragmentexample.SimpleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp" />
</LinearLayout>
Step 3: Open src -> package -> MainActivity.java
In this step we open MainActivity and add the code for initiate the Button. After that we perform
setOnClickListener on Button so whenever a user click on Button a message is displayed on the
screen with the help of Toast.
package com.abhiandroid.fragmentexample;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
MOBILE APPLICATION DEVELOPMENT 222
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Button activityButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get the reference of Button
activityButton = (Button) findViewById(R.id.activity_button);
// perform setOnClickListener event on Button
activityButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// display a message by using a Toast
Toast.makeText(getApplicationContext(), "Activity's Button", Toast.LENGTH_LONG).show();
}
});
}
}
Step 4: Now we create a fragment by right click on your package folder and create classes and
name it SimpleFragment and add the following code.
In this Fragment firstly we inflate the layout and get the reference of Button. After that we
perform setOnClickListener event on Button so whenever a user click on the button a message
―Fragment‘s Button― is displayed on the screen by using a Toast.
package com.abhiandroid.fragmentexample;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
public class SimpleFragment extends Fragment {
View view;
Button firstButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_simple, container, false);
// get the reference of Button
firstButton = (Button) view.findViewById(R.id.firstButton);
// perform setOnClickListener on first Button
firstButton.setOnClickListener(new View.OnClickListener() {
@Override

MOBILE APPLICATION DEVELOPMENT 223


public void onClick(View v) {
// display a message by using a Toast
Toast.makeText(getActivity(), "Fragment's Button", Toast.LENGTH_LONG).show();
}
});
return view;
}
}
Step 5: Now create a xml layouts by right clicking on res/layout -> New -> Layout
Resource File and name fragment_simple and add the following code in it.
Here we will design the basic simple UI by using TextView and Button
<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"
tools:context="com.abhiandroid.fragmentexample.SimpleFragment">
<!--TextView and Button displayed in Simple Fragment -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="Simple Fragment"
android:textColor="@color/black"
android:textSize="25sp" />

<Button
android:id="@+id/firstButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@color/green"
android:text="Fragment's Button"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
Step 6: Open res ->values ->colors.xml in this step we define the color‘s that used in our xml file.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- color's used in our project -->
<color name="black">#000</color>
<color name="green">#0f0</color>
<color name="white">#fff</color>

MOBILE APPLICATION DEVELOPMENT 224


<color name="button_background_color">#925</color>
</resources>
Step 7: Open AndroidManifest.xml
In this step we show the Android Manifest file in which do nothing because we need only one
Activitty i.e MainActivity which is already defined in it. In our project we a Fragment‘s but we
don‘t need to define the it in manifest because Fragment is a part of an Activity.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.abhiandroid.fragmentexample" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Output:

MOBILE APPLICATION DEVELOPMENT 225

You might also like