Mad PDF

Download as pdf or txt
Download as pdf or txt
You are on page 1of 254

Unit 1

Introduction to Android
Syllabus: The Android 4.1 jelly Bean SDK, Understanding the Android Software Stack, installing the
Android SDK, Creating Android Virtual Devices, Creating the First Android Project, Using the Text view
Control, Using the Android Emulator, The Android Debug Bridge(ADB), Launching Android Applications
on a Handset.

INTRODUCTION
When we talked about operating systems few years ago, the most common answers
were Windows, Linux, and mac operating system. However, with the undying competition in the
mobile phones market, the next big thing entered was ANDROID, which in no time became the
heart of smart phones. Android provides a rich application framework that allows you to build
innovative apps and games for mobile devices in a Java language environment.

Android is a mobile operating system developed by Google, based on a modified version of the
Linux kernel and other open source software and designed primarily for touch screen mobile devices
such as smart phones and tablets. In addition, Google has further developed Android TV for televisions,
Android Auto for cars, and Wear OS for wrist watches, each with a specialized user interface. Variants of
Android are also used on game consoles, digital cameras, PCs and other electronics.

The Android Operating System is a Linux-based OS developed by the Open Handset Alliance
(OHA). The Android OS was originally created by Android, Inc., which was bought by Google in 2005.
Google teamed up with other companies to form the Open Handset Alliance (OHA), which has become
responsible for the continued development of the Android OS.

The android is a powerful operating system and it supports large number of applications in
Smart phones. These applications are more comfortable and advanced for the users. The hardware that
supports android software is based on ARM architecture platform. The android is an open source
operating system means that it’s free and any one can use it.

The android has got millions of apps available that can help you managing your life one or other
way and it is available low cost in market at that reasons android is very popular.

Each time the OHA releases an Android version, it names the release after a dessert. Android 1.5 is
known as Cupcake, 1.6 as Donut, 2.0/2.1 as Eclair, 2.2 as Froyo and 2.3 is dubbed Gingerbread. Once a
version is released, so is its source code.

The Android OS is designed for phones. The important features of android are given below:
1) It is open-source.
2) Anyone can customize the Android Platform.
3) There are a lot of mobile applications that can be chosen by the consumer.
4) It provides many interesting features like weather details, opening screen, live RSS (Really Simple
Syndication) feeds etc.
It provides support for messaging services(SMS and MMS), web browser, storage (SQLite), connectivity
(GSM, CDMA, Blue Tooth, Wi-Fi etc.), media, handset layout etc.

Software developers who want to create applications for the Android OS can download the Android
Software Development Kit (SDK) for a specific version. The SDK includes a debugger, libraries, an
emulator, some documentation, sample code and tutorials. For faster development, interested parties
can use graphical integrated development environments (IDEs) such as Eclipse to write applications in
Java.

Android Emulator:

The Emulator is a new application in android operating system. The emulator is a new prototype that is used
to develop and test android applications without using any physical device.

The android emulator has all of the hardware and software features like mobile device except phone
calls. It provides a variety of navigation and control keys. It also provides a screen to display your
application. The emulators utilize the android virtual device configurations. Once your application is
running on it, it can use services of the android platform to help other applications, access the network,
play audio, video, store and retrieve the data.

Android versions:Google did not attach any high-calorie code name to its initial versions 1.0 and 1.1
of the Android Operating System. The code names of android ranges from A to N currently, such as
Aestro, Blender, Cupcake, Donut, Eclair, Froyo, Gingerbread, Honeycomb, Ice Cream Sandwitch, Jelly
Bean, KitKat, Lollipop and Marshmallow. Let's understand the android history in a sequence.
THE ANDROID 4.1 JELLY BEAN SDK
The Android 4.1 Jelly Bean SDK was released with new features for developers in July 2012. It improves
the beauty and simplicity of Android 4.0 and is a major platform release that adds a variety of new
features for users and app developers. A few of the big features of this release include the following:
• Project Butter—Makes the Jelly Bean UI faster and more responsive. Also CPU Touch Responsiveness
is added, which increases CPU performance whenever the screen is touched. It uses the finger’s speed
and direction to predict where it will be located after some milliseconds, hence making the navigation
faster.
• Faster speech recognition—Speech recognition is now faster and doesn’t require any network to
convert voice into text. That is, users can dictate to the device without an Internet connection.
• Improved notification system— The notifications include pictures and lists along with text.
Notifications can be expanded or collapsed through a variety of gestures, and users can block
notifications if desired. The notifications also include action buttons that enable users to call directly
from the notification menu rather replying to email.
• Supports new languages—Jelly Bean includes support for several languages including Arabic, Hebrew,
Hindi, and Thai. It also supports bidirectional text.
• Predictive keyboard—On the basis of the current context, the next word of the message is
automatically predicted.
• Auto-arranging Home screen—Icons and widgets automatically resize and realign as per the existing
space.
• Helpful for visually impaired users—The Gesture Mode combined with voice helps visually impaired
users to easily navigate the user interface.
• Improved Camera app—The Jelly Bean Camera app includes a new review mode of the captured
photos. Users can swipe in from the right of the screen to quickly view the captured photos. Also, users
can pinch to switch to a new film strip view, where they can swipe to delete photos.
• Better communication in Jelly Bean—Two devices can communicate with Near Field Communication
(NFC); that is, two NFC-enabled Android devices can be tapped to share data. Also, Android devices can
be paired to Bluetooth devices that support the Simple Secure Pairing standard by just tapping them
together.
• Improved Google Voice search—Jelly Bean is equipped with a question and answer search method
that helps in solving users’ queries similar to Apple’s popular Siri.
• Face Unlock—Unlocks the device when the user looks at it. It also prevents the screen from blacking
out. Optionally “blink” can be used to confirm that a live person is unlocking the device instead of a
photo.
• Google Now—Provides users “just the right information at just the right time.” It displays cards to
show desired information automatically. For example, the Places card displays nearby restaurants and
shops while moving; the Transit card displays information on the next train or bus when the user is near
a bus stop or railway station; the Sports card displays live scores or upcoming game events; the Weather
card displays the weather conditions at a user’s current location, and so on.
• Google Play Widgets—Provides quick and easy access to movies, games, magazines, and other media
on the device. It also suggests new purchases on Google Play.
• Faster Google Search—Google Search can be opened quickly, from the lock screen and from the
system bar by swiping up and also by tapping a hardware search key if it is available on the device.
• Supports antipiracy—This feature supports developers in the sense that the applications are
encrypted with a device-specific key making it difficult to copy and upload them to the Internet.
UNDERSTANDING THE ANDROID SOFTWARE STACK/ Android Architecture

The Android operating system is built on top of a modified Linux kernel. The software stack contains Java
applications running on top of a virtual machine. Components of the system are written in Java, C, C++,
and XML. Android operating system is a stack of software components which is roughly divided into five
sections
1) Linux kernel
2) Native libraries (middleware),
3) Android Runtime
4) Application Framework
5) Applications

1) Linux kernel
It is the heart of android architecture that exists at the root of android architecture. Linux kernel is
responsible for device drivers, power management, memory management, device management and
resource access. This layer is the foundation of the Android Platform.
 Contains all low level drivers for various hardware components support.
 Android Runtime relies on Linux Kernel for core system services like,
 Memory, process management, threading etc.
 Network stack
 Driver model
 Security and more.
2) Libraries
On top of Linux kernel there is a set of libraries including open-source Web browser engine
WebKit, well known library libc, SQLite database which is a useful repository for storage and
sharing of application data, libraries to play and record audio and video, SSL libraries responsible
for Internet security etc.
 SQLite Library used for data storage and light in terms of mobile memory footprints and task
execution.
 WebKit Library mainly provides Web Browsing engine and a lot more related features.
 The surface manager library is responsible for rendering windows and drawing surfaces of
various apps on the screen.
 The media framework library provides media codecs for audio and video.
 The OpenGl (Open Graphics Library) and SGL(Scalable Graphics Library) are the graphics
libraries for 3D and 2D rendering, respectively.
 The FreeType Library is used for rendering fonts.
3) Android Runtime
In android runtime, there are core libraries and DVM (Dalvik Virtual Machine) which is
responsible to run android application. DVM is like JVM but it is optimized for mobile devices. It
consumes less memory and provides fast performance. The Dalvik VM makes use of Linux core
features like memory management and multi-threading, which is intrinsic in the Java language.
The Dalvik VM enables every Android application to run in its own process, with its own instance
of the Dalvik virtual machine.

 Dalvik is a specialized virtual machine designed specifically


for Android and optimized for battery-powered mobile
devices with limited memory and CPU.
 Android apps execute on Dalvik VM, a “clean-room”
implementation of JVM
 Dalvik optimized for efficient execution
 Dalvik: register-based VM, unlike Oracle’s stack-based
JVM
 Java .class bytecode translated to Dalvik EXecutable (DEX)
bytecode, which Dalvik interprets

4) Android Framework
On the top of Native libraries and android runtime, there is android framework. Android
framework includes Android API's such as UI (User Interface), telephony, resources, locations,
Content Providers (data) and package managers. It provides a lot of classes and interfaces for
android application development.
• Activity Manager: manages the life cycle of an applications and maintains the back stack as well
so that the applications running on different processes has smooth navigations.
• Package Manager: keeps track of which applications are installed in your device.
• Window Manager : Manages windows which are java programming abstractions on top of lower
level surfaces provided by surface manager.
• Telephony Managers: manages the API which is use to build the phone applications
• Content Providers: Provide feature where one application can share the data with another
application. like phone number , address, etc
• View Manager : Buttons , Edit text , all the building blocks of UI, event dispatching etc.
5) Applications
• On the top of android framework, there are applications. All applications such as home, contact,
settings, games, browsers are using android framework that uses android runtime and libraries.
Android runtime and native libraries are using linux kernel. Any applications that you write are
located at this layer.

Android Studio Installation:

1)First of all, Download android studio from this link: https://developer.android.com/studio/index.html

2)JDK 8 is required when developing for Android 5.0 and higher (JRE is not enough). To check if you have JDK
installed (and which version), open a terminal and type javac -version. If the JDK is not available or the version is
lower than 6, download it from this link.

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

3)To set up Android Studio on Windows:

1. Launch the .exe file you just downloaded.

2. Follow the setup wizard to install Android Studio and any necessary SDK tools.

On some Windows systems, the launcher script does not find where Java is installed. If you encounter this
problem, you need to set an environment variable indicating the correct location.

Select Start menu > Computer > System Properties > Advanced System Properties. Then open Advanced
tab > Environment Variables and add a new system variable JAVA_HOME that points to your JDK folder, for
example C:\Program Files\Java\jdk1.8.x.( where x is version number).

To set up Android Studio on Mac OSX:

1. Launch the .dmg file you just downloaded.

2. Drag and drop Android Studio into the Applications folder.

3. Open Android Studio and follow the setup wizard to install any necessary SDK tools.

Depending on your security settings, when you attempt to open Android Studio, you might see a warning
that says the package is damaged and should be moved to the trash. If this happens, go to System
Preferences > Security & Privacy and under Allow applications downloaded from, select Anywhere. Then
open Android Studio again.

If you need use the Android SDK tools from a command line, you can access them at:

/Users/<user>/Library/Android/sdk/ To set up Android Studio on Linux:


1. Unpack the downloaded ZIP file into an appropriate location for your applications.
2. To launch Android Studio, navigate to the android-studio/bin/ directory in a terminal and execute studio.sh.
You may want to add android-studio/bin/ to your PATH environmental variable so that you can start Android
Studio from any directory.

3. Follow the setup wizard to install any necessary SDK tools.

Android Studio is now ready and loaded with the Android developer tools, but there are still a couple packages you
should add to make your Android SDK complete.

4)The SDK separates tools, platforms, and other components into packages you can download as needed using the
Android SDK Manager. Make sure that you have downloaded all these packages.

To start adding packages, launch the Android SDK Manager in one of the following ways:

 In Android Studio, click SDK Manager in the toolbar.


 If you're not using Android Studio:
Windows: Double-click the SDK Manager.exe file at the root of the Android SDK directory.

Mac/Linux: Open a terminal and navigate to the tools/ directory in the Android SDK, then execute android sdk.

5)Now get all the SDK tools, support libraries for additional APIs, Google Play services (if you need to use them ).
6)Once you've selected all the desired packages, continue to install:

Click Install X packages.

In the next window, double-click each package name on the left to accept the license agreement for each.

Click Install.

The download progress is shown at the bottom of the SDK Manager window. Do not exit the SDK Manager or it will
cancel the download.

7)Now that we have downloaded and installed everything we need. Enjoy your experience with Android. Best of luck
from Internshala.com

INSTALLING THE ANDRO ID SDK

For developing native Android applications that you can publish on the Google Play marketplace, you need to install
the following four applications:
• The Java Development Kit (JDK) can be downloaded from
http://oracle.com/technetwork/java/javase/downloads/index.html.
• The Eclipse IDE can be downloaded from http://www.eclipse.org/downloads/.
• The Android Platform SDK Starter Package can be download from http://developer.android.com/sdk/index.html.
• The Android Development Tools (ADT) Plug-in can be downloaded from
http://developer.android.com/sdk/eclipse-adt.html. The plug-in contains project templates and Eclipse tools that
help in creating and managing Android projects.
The Android SDK is not a full development environment and includes only the core SDK Tools, which are used to
download the rest of the SDK components. This means that after installing the Android SDK Tools, you need to
install Android platform tools and the other components required for developing Android applications. Go

7
to http://developer.android.com/sdk/index.html and download the package by selecting the link for your operating
system.
The first screen is a Welcome screen. Select the Next button to move to the next screen. Because the Android SDK
requires the Java SE Development Kit for its operation, it checks for the presence of JDK on your computer.
If Java is already installed on your computer before beginning with Android SDK installation, the wizard detects its
presence and displays the version number of the JDK found on the machine, as shown in Figure.

Figure Dialog box informing you that the JDK is already installed on the computer

Select the Next button. You get a dialog box asking you to choose the users for which Android SDK is being installed.
The following two options are displayed in the dialog box:
• Install for anyone using this computer
• Install just for me
Select the Install for anyone using this computer option and click Next. The next dialog prompts you for the location
to install the Android SDK Tools, as shown in below Figure . The dialog also displays the default directory location for
installing Android SDK Tools as C:\Program Files (x86)\Android\android-sdk, which you can change by selecting
the Browse button. Keep the default directory for installing Android SDK Tools unchanged; then select
the Next button to continue.

8
The next dialog box asks you to specify the Start Menu folder where you want the program’s shortcuts to appear, as
shown.

Figure: Dialog box to select the Start menu shortcut folder

A default folder name appears called Android SDK Tools. If you do not want to make a Start Menu folder, select
the Do not create shortcuts check box. Let’s create the Start Menu folder by keeping the default folder name and
selecting the Install button to begin the installation of the Android SDK Tools. After all the files have been
downloaded and installed on the computer, select the Next button. The next dialog box tells you that the Android
SDK Tools Setup Wizard is complete and the Android SDK Tools have successfully installed on the computer.
Select Finish to exit the wizard, as shown in Figure

9
Figure: Successful installation of the Android SDK Tools dialog box

Note that the check box Start SDK Manager (to download system images) is checked by default. It means that after
the Finish button is clicked, the Android SDK Manager, one of the tools in the Android SDK Tools package, will be
launched. Android SDK is installed in two phases. The first phase is the installation of the SDK, which installs the
Android SDK Tools, and the second phase is installation of the Android platforms and other components.
An Android application is a combination of several small components that include Java files, XML resource and
layout files, manifest files, and much more. It would be very time-consuming to create all these components
manually. So, you can use the following applications to help you:
• Eclipse IDE—An IDE that makes the task of creating Java applications easy. It provides a complete platform for
developing Java applications with compiling, debugging, and testing support.
• Android Development Tools (ADT) plug-in—A plug-in that’s added to the Eclipse IDE and automatically creates
the necessary Android files so you can concentrate on the process of application development.
Before you begin the installation of Eclipse IDE, first set the path of the JDK that you installed, as it will be required
for compiling the applications. To set the JDK path on Windows, right-click on My Computer and select
the Properties option. From the System Properties dialog box that appears, select the Advanced tab, followed by
the Environment Variables button. A dialog box, Environment Variables, pops up. In the System variables section,
double-click on the Path variable. Add the full path of the JDK (C:\Program Files\Java\jdk1.7.0_04\bin\java.exe) to
the path variable and select OK to close the windows.

CREATING ANDROID VIRTUAL DEVICES

An Android Virtual Device (AVD) represents a device configuration. There are many Android devices, each
with different configuration. To test whether the Android application is compatible with a set of Android devices,
you can create AVDs that represent their configuration. For example, you can create an AVD that represents an
Android device running version 4.1 of the SDK with a 64MB SD card. After creating AVDs, you point the emulator to
each one when developing and testing the application. AVDs are the easiest way of testing the application with
various configurations.

10
To create AVDs in Eclipse, select the Window, AVD Manager option. An Android Virtual Device
Manager dialog opens, as shown in Figure. The dialog box displays a list of existing AVDs, letting you create new
AVDs and manage existing AVDs. Because you haven’t yet defined an AVD, an empty list is displayed.

Figure: The AVD Manager dialog

Select the New button to define a new AVD. A Create new Android Virtual Device (AVD)dialog box, appears The
fields are as follows:
• Name—Used to specify the name of the AVD.
• Target—Used to specify the target API level. Our application will be tested against the specified API level.
• CPU/ABI—Determines the processor that we want to emulate on our device.
• SD Card—Used for extending the storage capacity of the device. Large data files such as audio and video for which
the built-in flash memory is insufficient are stored on the SD card.
• Snapshot—Enable this option to avoid booting of the emulator and start it from the last saved snapshot. Hence,
this option is used to start the Android emulator quickly.
• Skin—Used for setting the screen size. Each built-in skin represents a specific screen size. You can try multiple skins
to see if your application works across different devices.
• Hardware—Used to set properties representing various optional hardware that may be present in the target
device.
In the AVD, set the Name of the AVD to demoAVD, choose Android 4.1—API Level 16 for the Target, set SD
Card to 64 MiB, and leave the Default (WVGA800) for Skin.
In the Hardware section, three properties are already set for you depending on the selected target. The Abstracted
LCD density is set to 240; the Max VM application heap size is set to 48, and the Device RAM size is set to 512.
You can select these properties and edit their values, delete them, and add new properties by selecting
the New button. New properties can include Abstracted LCD density, DPad support, Accelerometer, Maximum
horizontal camera pixels, Cache partition size, Audio playback support, and Track-ball support, among others.

Note 11
You learn about the API and its different levels in Chapter 2, “Basic Widgets.” The new AVD, demoAVD, is created and
Note
displayed in the list of existing AVDs.
The larger the allocated SD Card space, the longer it takes to create the AVD. Unless it is really required, keep the SD Card
space as low as possible. I would recommend keeping this small, like 64MiB.
Finally, select the Create AVD button (see Figure 1.20—right) to see how to create the virtual device
called demoAVD.

You now have everything ready for developing Android applications—the Android SDK, the Android platform, the
Eclipse IDE, the ADT plug-in, and an AVD for testing Android applications. You can now create your first Android
application.
Creating the First Android Project
Now let’s go over how to set up your first project so all you’ll have left to do is write! you'll start a new Android
Studio project and get to know the project workspace, including the project editor that you'll use to code the app.
Step 1: Setup Eclipse IDE:Install the latest version of Eclipse. After successful installation, it should display a

Step 2: Setup Android Development Tools (ADT) Plugin

Here you will learn to install the Android Development Tool plugin for Eclipse. To do this, you have to click on Help >
Software Updates > Install New Software. This will display the following dialogue box.

12
Just click on the Add button as shown in the picture and add https://dl-ssl.google.com/android/eclipse/ as the
location. When you press OK, Eclipse will start to search for the required plug-in and finally it will list the found plug-
ins.

Step 3: Configuring the ADT plugin


After the installing ADT plugin, now tell the eclipse IDE for your android SDK location. To do so:
1. Select the Window menu > preferences
2. Now select the android from the left panel. Here you may see a dialog box asking if you want to send the
statistics to the google. Click proceed.
3. Click on the browse button and locate your SDK directory e.g. my SDK location is C:\Program
Files\Android\android-sdk .
4. Click the apply button then OK.

13
Step 4: Create Android Virtual Device:
The last step is to create Android Virtual Device, which you will use to test your Android applications. To do this,
open Eclipse and Launch Android AVD Manager from options Window > AVD Manager and click on New which will
create a successful Android Virtual Device. Use the screenshot below to enter the correct values.

USING THE TEXTVIEW CONTROL


In android ui or input controls are the interactive or View components which are used to design the user
interface of an application. In android we have a wide variety of UI or input controls available, those are TextView,
EditText, Buttons, Checkbox, Progressbar, Spinners, etc.
In android, TextView is a user interface control which is used to set and display the text to the user based on
our requirements. The TextView control will act as like label control and it won’t allow users to edit the text. A good
example of TextView control usage would be to display textual labels for other controls, like "Enter a Date:", "Enter
a Name:" or "Enter a Password:".
In android, we can create a TextView control in two ways either in XML layout file or create it in Activity file
programmatically.
Specific attributes of TextView controls you will want to be aware of:
 Give the TextView control a unique name using the id property.
 Set the text displayed within the TextView control using the text property; programmatically set with the
setText() method.
 Set the layout height and layout width properties of the control as appropriate.
 Set any other attributes you desire to adjust the control’s appearance. For example, adjust the text size,
color, font or other style settings.
 By default, text contents of a TextView control are left-aligned. However, you can position the text using the
gravity attribute. This setting positions your text relative to the control’s overall width and height and only
really makes sense to use if there is whitespace within the TextView control.
 In XML, this property would appear within your TextView control as:
android:gravity="center"

14
 By default, the background of a TextView control is transparent. That is, whatever is behind the control is
shown. However, you can set the background of a control explicitly, to a color resource, or a drawable
(picture). In XML, this property would appear within your TextView control as:

android:background="#0000ff"
 By default, any text contents within a TextView control is displayed as plain text. However, by setting one
simple attribute called autoLink, all you can enable automatic detection of web, email, phone and address
information within the text. In XML, this property would appear within your TextView control as:
android:autoLink="all"
 You can control the color of the text within the TextView control
by using the textColor attribute. This attribute can be set to a color resource, or a specific color by hex value.
In XML, this property would appear within your TextView control as:

android:textColor="#ff0000"
 You can control the style of the text (bold, italic) and font family (sans, serif, monospace) within the TextView
control by using the textStyle and typeface attributes. In XML, these properties would appear within your
TextView control as:
android:textStyle="bold"
android:typeface="monospace"

Example:

<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".HelloWorldAppActivity"
android:typeface="serif"
android:textColor="#0F0"
android:textSize="25dp"
android:textStyle="italic"
android:gravity="center_horizontal" />

This code makes the text of the TextView control appear in serif font, green color, 25dp size, italic, and at the
horizontal center of the container

USING THE ANDROID EMULATOR


The Android emulator is used for testing and debugging applications before they are loaded onto a real handset.
Android emulator is typically used for deploying apps that are developed in your IDE without actually installing it in a
device. Android emulators such as Bluestacks can run android apps where in which emulators like AVD and
genymotion are used to emulate an entire operating system. The Android emulator is integrated into Eclipse
through the ADT plug-in.

15
Limitations of the Android Emulator
The Android emulator is useful to test Android applications for compatibility with devices of different configurations.
But still, it is a piece of software and not an actual device and has several limitations:
• Emulators no doubt help in knowing how an application may operate within a given environment, but they still
don’t provide the actual environment to an application. For example, an actual device has memory, CPU, or
other physical limitations that an emulator doesn’t reveal.
• Emulators just simulate certain handset behavior. Features such as GPS, sensors, battery, power settings, and
network connectivity can be easily simulated on a computer.
• SMS messages are also simulated and do not use a real network.
• Phone calls cannot be placed or received but are simulated.
• No support for device-attached headphones is available.
• Peripherals such as camera/video capture are not fully functional.
• No USB or Bluetooth support is available.
The emulator provides some facilities too. You can use the mouse and keyboard to interact with the emulator when
it is running. For example, you can use your computer mouse to click, scroll, and drag items on the emulator. You
can also use it to simulate finger touch on the soft keyboard or a physical emulator keyboard. You can use your
computer keyboard to input text into UI controls and to execute specific emulator commands. Some of the most
commonly used commands are
• Back [ESC button]
• Call [F3]
• End [F4]
• Volume Up [KEYPAD_PLUS, Ctrl-5]
• Volume down [KEYPAD_MINUS, Ctrl-F6]
• Switching orientations [KEYPAD_7, Ctrl-F11/KEYPAD_9, Ctrl-F12]

16
You can also interact with an emulator from within the DDMS tool. Eclipse IDE provides three perspectives to work
with: Java perspective, Debug perspective, and DDMS perspective. The Java perspective is the default and the one
with which you have been working up to now. You can switch between perspectives by choosing the appropriate
icon in the top-right corner of the Eclipse environment. The three perspectives are as follows:

• The Java perspective—It’s the default perspective in Eclipse where you spend most of the time. It shows the
panes where you can write code and navigate around the project.

• The Debug perspective—Enables application debugging. You can set breakpoints; step through the code; view
LogCat logging information, threads, and so on.

• The Dalvik Debug Monitor Service (DDMS) perspective—Enables you to monitor and manipulate emulator and
device status. It also provides screen capture and simulates incoming phone calls, SMS sending, and GPS
coordinates. To manage content in the device or emulator, you can use the ADB (Android Debug Bridge).

THE ANDROID DEBUG BRIDGE(ADB)

The Android-Debug-Bridge (abbreviated as adb) is a software-interface for the android system, which can be used to
connect an android device with a computer using an USB cable or a wireless connection. It can be used to execute
commands on the phone or transfer data between the device and the computer.[1]

The tool is part of the Android SDK (Android Software Development Kit) and is located in the subdirectory platform-
tools. In previous versions of the SDK it was located in the subdirectory tools.

The Android Debug Bridge is a software interface between the device and the local computer, which allows the
direct communication of both components. This includes the possibility to transfer files from one component to the
other one, as well as executing commands from the computer on the connected device. The ADB can be used
through a command line windows, terminal/shell in Linux-based systems, a command line (cmd) for Windows. The
main advantage is to execute commands on the phone directly out of the computer, without any direct user
interaction to the phone, which makes especially debugging a lot easier.

It is a client-server program that includes three components:

 A client, which sends commands. The client runs on your development machine. You can invoke a client
from a command-line terminal by issuing an adb command.
 A daemon (adbd), which runs commands on a device. The daemon runs as a background process on each
device.
 A server, which manages communication between the client and the daemon. The server runs as a
background process on your development machine.

When you start an adb client, the client first checks whether there is an adb server process already running. If
there isn't, it starts the server process. When the server starts, it binds to local TCP port 5037 and listens for
commands sent from adb clients—all adb clients use port 5037 to communicate with the adb server.
The server then sets up connections to all running devices. It locates emulators by scanning odd-numbered ports
in the range 5555 to 5585, the range used by the first 16 emulators. Where the server finds an adb daemon (adbd),

17
it sets up a connection to that port. Note that each emulator uses a pair of sequential ports — an even-numbered
port for console connections and an odd-numbered port for adb connections.
Once the server has set up connections to all devices, you can use adb commands to access those devices.
Because the server manages connections to devices and handles commands from multiple adb clients, you can
control any device from any client
Launching Android Applications on a Handset

To load an application onto a real handset, you need to plug a handset into your computer, using the USB data
cable. You first confirm whether the configurations for debugging your application are correct and then launch the
application as described here:

1. In Eclipse, choose the Run, Debug Configurations option.

2. Select the configuration HelloWorldApp_configuration, which you created for the HelloWorldApp application.

3. Select the Target tab, set the Deployment Target Selection Mode to Manual. The Manual option allows us to
choose the device or AVD to connect to when using this launch configuration.

4. Apply the changes to the configuration file by clicking the Apply button.

5. Plug an Android device into your computer, using a USB cable.

6. Select Run, Debug in Eclipse or press the F11 key. A dialog box appears, showing all available configurations for
running and debugging your application. The physical device(s) connected to the computer are also listed. Double-
click the running Android device. Eclipse now installs the Android application on the handset, attaches a debugger,
and runs the application.

Android Studio Project Structure

Android studio shows a structured view of the project files and also provides a quick access to source files
also. Android studio groups all the required source files, build files, resource files of all the modules at the
top of project view.

Let`s first understand the anatomy of the Android Studio:

18
1) .idea: This folder contains the directories (subfolders) for IntelliJ IDEA settings.

2) app: It contains the actual application code(source files, resource file and manifest files). It further
contains the following sub-directories :
a) bulid: This folder has sub-folders for the build-variants. The app/build/output/apk directory contains
packages named app-<flavor>-<built-type>.apk. So different variant of the single app resides here.
b) libs: As the name suggests, this folder has all the .jar files and the library files.

3) src: Here you will see two sub-directories androidTest and main.
In androidTest the application code for testing purpose is created by android automatically.
This helps in building testing packages without modifying the building files and the application code.

main contains the all the source .java files including the stub mainactivity.java.

The res directory is where you will find the resources like drawable files, menu, values ( style files,
string values, dimension values).

Sub-directories of res folder


 anim/: For XML files that are compiled into animation objects.
 color/: For XML files that describe colors.

19
 drawable/:For image files (PNG, JPEG, or GIF), 9-Patch image files, and XML files that describe
Drawable shapes or Drawable objects that contain multiple states (normal, pressed, or focused).
 mipmap/: For app launcher icons. This folder contains additional sub-folders for different screen
resolutions. Once an image is imported into this folder, Studio automatically resizes the image
into different resolutions and places them in the appropirate folders. This behavior allows
launcher apps to pick the best resolution icon for your app to display on the home screen. To see
how to import an image into the mipmap folder, please read about using 'Image asset'.
 layout/: XML files that are compiled into screen layouts (or parts of a parent layout).
 menu/: For XML files that define application menus.
 values/: For XML files that define constants that can be accessed in other XML and Java files.

R.java

R.java is an uneditable file auto-generated by Studio, whenever we modify the XML content. This file
links the XML values to Java files. Whenever we need to use XML values in a Java file, we call these
values using the R class.
The following images show a sample XML file, where a string variable named 'title' is assigned a value of
'Internshala - Tic Tac Toe'. This variable is then accessed in a java file using the R class.
4) Gradle scripts: With Android studio, Google switched to the new advanced building system, Gradle. It
is a JVM based build system. If you want to make the package building task automatically, then you can
write your own script in java or groovy and distribute it. Gradle allows to create different variants apk
files for the same application project. We will learn about Gradles in the later chapters.
5) External Libraries: This is the place where all the referenced libraries and the information about the
targeted platform SDK are stored.

What is Build system and Gradle

The build system is responsible to build, test an android system and also prepare the deployable files for
the specified platform. In simple words, build system generates the .apk files for the application project.

With Android Studio, the advanced build system allows the developers to configure the build systems
manually, create different variant APK files from single project (without modifying the execution code)
and share the code and resources from other modules. Before Android Studio, Eclipse was the IDE used
for android development. Eclipse kept all the .java files (in src directory) and resource files (in res
directory) in the same directory. That allows the build system to group all the files into an intermediate
code and finally generates .apk file.
Android Studio uses Gradle as its build system. One intriguing feature that Gradle offers is that it allows
you to write your own script to automate the task of building an app. As Gradle is plug-in based system, if
you have your own programming language then you can write the plug-in in the script using java or
groovy and share it with other developers too. Isn`t that cool?

20
‘Hello World’ APP
The first you will be creating will be “Hello World”! We will see how to start a project in Android Studio. First
of all, launch Android Studio. Goto File-> New Project. Give the name of the application. Here we name it
“Hello_World”. Hit next.

Select the category of the target devices and the desire minimum target platform of android:

Now, select the main activity style depending upon the needs. Here for “Hello_world”,

21
select blank activity.

Name the main_activity files, which are the first activity to be displayed in the application. Click ‘finish’.
Run the Application.
Building and Running an App

First you need to build your application project before running it on the device. Click on the “build” icon from
the toolbar and then select “Make project”.
To Run an application:
Select “Run” from the toolbar and then “run app”.
You can run your app on the emulator or on a real-device from Android Studio. This is done using the debug
version of the app. Run configuration defines which module will run, which activity is start, and about all the
AVD settings. If you run the android application for the first time, android studio will automatically create a
run configuration and choose AVD to run it. Though you can create or modify the run configuration.
Run an app on Emulator:
When you run an app on the emulator, first make sure about the AVD (Android Virtual Device). You can
choose from the available AVD or create a new AVD.
Go to Tools >Android > AVD Manager. Click on ‘create virtual device’.
Choose Hardware category and configuration, Click next. Select the desired system version and create the
AVD.
To run application on the desired AVD, click on the launch button.
Run an App on the real-device :
First, you have to make sure that the real-device in which you desire to run your app, is debuggable.
1) Check if the android:debuggable attribute is set to true in the build.gradle file. If not then, you cannot
debug it. Make it true in case you want to run it on real-device.
2) Please enable the USB Debugging, in the device. In android 4.2 or above, the developer option can be
enabled by going to Settings > About Phone and tapping Build Number 7 times. Now you can see the
Developer Option in the previous screen.
Now, when you have your AVD set up or the real-devices ready, go to Run > Run (OR Run > Debug). If you
don’t see your device in the AVD window, then you need to download appropriate device drivers for your
device from the internet.

22
UNIT-2
Basic Widgets
Syllabus: Understanding the Role of Android Application Components, Understanding the Utility of Android
API, Overview of the Android Project Files, Understanding Activities, Role of the Android Manifest File, Creating
the User Interface, Commonly Used Layouts and Controls, Event Handling, Displaying Messages Through Toast,
Creating and Starting an Activity, Using the Edit Text Control, Choosing Options with Checkbox, Choosing
Mutually Exclusive Items Using Radio Buttons
Understanding the Role of Android Application Components
Almost all popular applications are interactive. These applications interact with the user, and, depending on
the data supplied by the user, desired actions and/or processing are performed. The user interface controls thus
play a major role in getting feedback from the user.
Application components are the ones which when combined together, offers you a brilliant Android
application. So, these components exactly act as the building blocks of an Android application. The information
regarding all the application components is provided in the manifest file, which is AndroidManifest.xml. This file
will help you in understanding the use of each and every application component and how do they interact with
each other. Android provides four important components to build any android application.
 Activities
 Services
 Intent and broadcast receivers
 Content Providers

1. Activities-
Activities are said to be the presentation layer of our applications. An activity is the first stepping stone is
building an Android user application. The UI of our application is build around one or more extensions of the
Activity class.
An activity in android is like your computer welcome screen which presents single user display. In other
words, Activity in android represents single screen with a user interface. We can understand Activity in terms of
web applications For example: We creates numbers of web pages to build complete web application, similarly
on the other hand android application consist of several Activities to run as a complete application. There is one
“main” activity. All other activities are child activities. There is a stack called back stack. Whenever, there is a
new window is started, previous activity is pushed to the back stack and it is stopped until the new activity is

1
done. As soon as the back key of your device is pressed, new activity is popped out of stack and destroyed. Now
previous activity resumes.
2. Services-
These are like invisible workers of our app. These components run at backend, updating your data sources
and Activities, triggering Notification and also broadcast Intents. They also perform some tasks when
applications are not active. This component is responsible for handling the time taking operations which
generally runs in the background of the operating system (in this case, Android). The simple example of the
service component is that when you play music on your mobile phone, you will be able to use other applications
too. A service can take two forms:
1. Started: After a service starts, it can run indefinitely and usually performs single operation. No result is
returned to user. For example, uploading a file. After the task is completed, it should terminate itself.
2. Bound: In this case, a component is bound to a service so that a particular task can be completed. This
type of service provides a client-server like interface. Requests can be send, receive requests, and return
result to the user. Inter process communication is achieved through this service.
3.Intents and Broadcast Receivers-
Android Intent is the message that is passed between components such as activities, content
providers, broadcast receivers, services etc. It is generally used with startActivity() method to invoke activity,
broadcast receivers etc. It binds individual components to each other.
Broadcast Receivers simply respond to broadcast messages from other applications or from the system
itself. These messages are sometime called events or intents. For example, applications can also initiate
broadcasts to let other applications know that some data has been downloaded to the device and is available
for them to use, so this is broadcast receiver who will intercept this communication and will initiate appropriate
action. another example is, when your device boots up or switched on, the system generates a broadcast to all
apps. There should be a procedure or should be something which can receive these broadcasts. These receptors
are called broadcast receivers. There are two types of broadcasts:
1. Normal Broadcasts: These are asynchronous in nature. Many receivers can be activated at the same
time which doesn’t have any defined order. But they are very efficient.
2. Ordered Broadcasts: They are synchronous in nature. Broadcast received by one receiver passes it to
other receivers. Broadcasts are delivered to receiver on one-to-one and sequential basis. Either
receiver will pass result to another receiver or it may completely destroy the broadcast.
Content Providers-
It is used to manage and persist the application data also typically interact with SQL database. They are also
responsible for sharing the data beyond the application boundaries. The Content Providers of a particular
application can be configured to allow access from other applications, and the Content Providers exposed by
other applications can also be configured.
With content providers we can save data in SQLite database, on the web or any other persistent storage
location, where application can easily access the data. This component is useful in reading and writing private
data. For example: we can read and write important reminders or notes in database(within an application).

2
Android Widgets and Notifications
Android App widgets are the small application views. These views can be embedded into other applications.
They can receive updates on periodic basis. A widget is a quick view of your app’s functionality and data. This
view is accessible from home screen of your device. Now widgets are of following types:
1. Informational Widget: These Android widgets are going to display only that information to user which is
important and dynamic in nature. Example the information displayed on your home screen saying time and
weather condition is a widget of this type.

2.Collection Widgets: These Android widgets scroll in top-to-down direction. Collection of information of
same type and then enabling user to open any one of them to full detail. Example is your e-mail app which will
display all the mails in your inbox and then allow you to open any one o them.
3.Control Widgets: Displays the most frequently used functionalities which user might want to control from
home screen. For example in a video app, you can pause, play, stop, go to previous track, move to next track is
an example of control widget.
4.Hybrid Widgets: These Android widgets combine features of all of the above three.
Notification, as the name says keeps the user aware of events going on. User is kept informed like any news
channel. For e.g, everyone of us know about facebook or whatsapp, now notification system of app is
responsible for informing you about any new friend request, chat request, or a new message from say, dvs or
xyz, etc.
There are a few other application components that you should be aware of. These application components
include fragments, views, layouts, intents, resources, and manifest. All of these components are used for the
creation of above components.
S.No. Application Components Description
* Represents the fragments of a user interface in the Activity
1 Fragments
component
* Includes the user interface elements like buttons, drop-down
2 Views
lists, etc.
* Controls the screen format based on different hierarchies of the
3 Layouts views
* Takes care of the appearance of the views on the screen
4 Intents * Wires the messages of different components together
* Includes external elements like drawable or editable pictures,
5 Resources
strings, and constants
3
* Carries the information regarding the applications
6 Manifest
* Configuration file

UNDERSTANDING THE UTILITY OF ANDROID API


API is the acronym for Application Programming Interface, which is a software intermediary that allows
two applications to talk to each other. Each time you use an application, you’re using an API.
When you use an application on your mobile phone, the application connects to the Internet and sends
data to a server. The server then retrieves that data, interprets it, performs the necessary actions and sends it
back to your phone. The application then interprets that data and presents you with the information you
wanted in a readable way. This is what an API is - all of this happens via API.
In computer programming, an application programming interface (API) is a set of subroutine
definitions, protocols, and tools for building an application. An API specifies how software components should
interact and APIs are used when programming graphical user interface (GUI) components. In general terms, it
is a set of clearly defined methods of communication between various components. A good API makes it
easier to develop a computer program by providing all the building blocks, which are then put together by the
programmer.
API Level is an integer value that uniquely identifies the framework API revision offered by a version of
the Android platform.
The Android platform provides a framework API that applications can use to interact with the underlying
Android system. The framework API consists of:
 A core set of packages and classes
 A set of XML elements and attributes for declaring a manifest file
 A set of XML elements and attributes for declaring and accessing resources
 A set of Intents
 A set of permissions that applications can request, as well as permission enforcements included in the
system
The following table specifies the API Level supported by each version of the Android platform.
,,
Each successive version of the Android platform can include updates to the Android application framework API
that it delivers. The framework API is specified through an integer called API level, and each Android platform
version supports exactly one API level, although backward compatibility is there; that is, earlier API levels are
supported. The initial release of the Android platform provided API Level 1, and subsequent releases have
incremented the API level.
Updates to the framework API are designed so that the new API remains compatible with earlier
versions of the API. That is, most changes in the API are additive and introduce new or replacement
functionality. As parts of the API are upgraded, the older replaced parts are deprecated but are not removed,
so that existing applications can still use them. In a very small number of cases, parts of the API may be
modified or removed.
The framework API that an Android platform delivers is specified using an integer identifier called "API
Level". Each Android platform version supports exactly one API Level, although support is implicit for all earlier

4
API Levels (down to API Level 1). The initial release of the Android platform provided API Level 1 and
subsequent releases have incremented the API Level.
Uses of API Level in Android
The API Level identifier serves a key role in ensuring the best possible experience for users and
application developers:
 It lets the Android platform describe the maximum framework API revision that it supports
 It lets applications describe the framework API revision that they require
 It lets the system negotiate the installation of applications on the user's device, such that version-
incompatible applications are not installed.
 Each Android platform version stores its API Level identifier internally, in the Android system itself.

OVERVIEW OF THE ANDROID PROJECT FILES

The following files and directories are created for the Android application. The list below is just an overview of
the files and directories
• /src folder— The folder that contains the entire Java source file of the application. The folder contains a
directory structure corresponding to the package name supplied in the application. The folder contains the
project’s default package: com.company.basichelloworld. On expanding the package, you find the Activity of
the application, the MainActivity.java file, within it.
• /src/com.company.basichelloworld — Refers to the package name of the application. To avoid any collision
among the class names, variable names, and so on used in the application with those of other Android
applications, each application has to be packaged in a unique container.
• /src/com.company.helloworld/MainActivity.java- The default Activity file of the application. Recall that
each application has at least one Activity that acts as the main entry point to the application. The Activity file is
automatically defined as the default launch Activity in the Android Manifest file.
• /gen folder—Contains Java files generated by ADT on compiling the application. That is, the gen folder will
come into existence after compiling the application for the first time. The folder contains two files
1. R.java: file that contains references for all the resources defined in the res directory.
2. BuildConfig.java: file that is used to run code only in debug mode. It contains a DEBUG constant that
helps in running debug-only functions.
• /gen/com.company.basichelloworld/R.java—All the layout and other resource information that is coded in
the XML files is converted into Java source code and placed in the R.java file. It also means that the file
contains the ID of all the resources of the application. The R.java file is compiled into the Java byte code files
and then converted into .dex format. You should never edit this file by hand, as it is automatically overwritten
when you add or edit resources.
• /assets folder—The assets folder is empty by default. It stores raw asset files that may be required in the
application. It may contain fonts, external JAR files, and so on to be used in the application. The assets folder is
like a resource folder where uncompiled resources of the project are kept and no IDs are generated for the
resources kept here.

5
• Android SDK jar file—The jar file for the target platform
• /bin folder—The folder that stores the compiled version of
the application.
• /res folder—The folder where all application resources
(images, layout files, and string files) are kept. Instead of
hard coding an image or string in an application, a better
approach is to create a respective resource in the res folder
and include its reference in the application. Each resource is
assigned a unique resource ID, which automatically appears
in the R.java file and thus in the R class after compilation,
enabling us to refer to the resource in the code
• /res/drawable-xhdpi, /res/drawable-hdpi, /res/drawable-
mdpi, /res/drawable-ldpi—the application’s icon and
graphic resources are kept in these folders. Because devices
have screens of different densities, the graphics of different
resolutions are kept in these folders. Usually, graphics of
320dpi, 240dpi, 160dpi, and 120dpi are used in Android
applications. The application picks up the graphic from the
correct folder after determining the density of the current
device.
• /res/layout—Stores the layout file(s) in XML format.
• /res/values—Stores all the values resources. The values
resources include many types such as string resource,
dimension resource, and color resource.
• /res/layout/activity_main.xml—The layout file used
by MainActivity to draw views on the screen. The views or
controls are laid in the specified layout.
• /res/values/strings.xml—Contains the string resources.
String resources contain the text matter to be assigned to
different controls of the applications.
• AndroidManifest.xml—The central configuration file for
the application. It is one of the most important file in the
Android project structure. It contains information of the
package, including components of the application such as
activities, services, broadcast receivers, content providers.

Figure: Package Explorer window showing different directories, subdirectories, and files automatically created by ADT
• project.properties—A build file used by Eclipse and the Android ADT plug-in. It contains project settings such
as the build target. You can use this file to change various properties of the project. If required, the file should
not be edited directly but through editors available in Eclipse.
It’s clear that the Java Activity file is the main file that drives the entire Android application.

6
UNDERSTANDING ACTIVITIES

An Activity is a single screen in Android. It is like a window in a desktop app, or a Frame in a Java
program. An Activity allows you place all your UI components or widgets together on the screen. Every unique
screen the user interacts with in an application is displayed through an Activity—one Activity for each screen.
Users can interact with an application by performing different actions with the visual controls found in the
Activity. A simple application may consist of just one Activity, whereas large applications contain several
Activities. Each Activity of an application operates independently of the others.
If you have worked with C, C++ or Java programming language then you must have seen that your
program starts from main() function. Very similar way, Android system initiates its program with in an Activity
starting with a call on onCreate() callback method. There is a sequence of callback methods that start up an
activity and a sequence of callback methods that tear down an activity.
A stack of Activities is maintained while running an application, and the Activity at the top of the stack
is the one currently being displayed. When the Back button is pressed, the Activity is popped from the stack,
making the previous Activity the current Activity, which therefore displays the previous screen. The transition
from one Activity to another is accomplished through the use of asynchronous messages called intents.
Intents can be used to pass data from one Activity to another. All of the Activities in the application must be
defined in the Application’s manifest file, an XML file that keeps track of all the components and permissions
of the application.
Each Activity in an Android application is either a direct subclass of the Activity base class or a subclass
of an Activity subclass.
Activity life cycle
Activities have life cycles and inherit a set of life cycle methods from the Activity base class that are
executed when the corresponding life cycle state of the Activity is reached.
The Android Activity life cycle defines the states or events that an Activity goes through from the time it is
created until it finishes running. The Activity monitors and reacts to these events by executing methods that
override the Activity class methods for each event.
Each time the Activity state changes, one of the following lifecycle methods will be called on the Activity
class. The lifecycle method of Activity describes how activity will behave at different states

 onCreate(): This is called when the Activity is first initialized. You need to implement this method in
order to do any initialization specific to your Activity. Views are created, bind data, etc. A Bundle object
is passed where all the previous activity states are captured.
 onStart(): This is called the first time that the Activity is about to become visible to the user, as the
Activity prepares to come to the foreground become interactive. Once this callback finishes, the
onResume() method will be called.
 onResume(): When the Activity goes into this state, it begins to interacts with the user. The Activity
continues in this state till something happen to take focus from the app or Activity (such as an
incoming call). When this happens, the onPause() method will be called.

7
 onPause(): This method is used to pause operations that should not happen when the Activity is in
paused state. A call to this method indicates that the user is leaving the app. For example, in a music
player app, an incoming call will cause the app to transition into a paused state. This should mute or
pause the currently playing music. When the user returns to the app, the onResume() method will be
called.
 onStop(): This method is called when the Activity is no longer visible in the app. It can happen, for
example, when another Activity has been loaded and is taking the full screen of the device. When this
method is called, the Activity is said to be in a stopped state. In this state, the system either calls the
onRestart() to bring back interactivity with Activity. Or it calls the onDestroy() method to destroy the
Activity.
 onDestroy(): This gets called before the Activity is destroyed. The system calls this method when a user
terminates the Activity, or because the system is temporarily destroying the process that contains the
Activity to save space. Be sure to free up any resources your Activity has created in this method, or else
your app will have a memory leak!
 onRestart(): This gets called when an Activity restarts after it had been stopped.
All the activities of an application, permissions, and intents are defined through the XML-structured manifest
file AndroidManifest.xml. For each Activity, there needs to be an entry in the AndroidManifest.xml file, where
you can define labels, permissions, and so on. In fact, the manifest file is the configuration file where all the
different components of the application are defined.
Example: program to demonstrate the life cycle methods of an activity
import android.app.Activity;
8
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("lifecycle","onCreate invoked");
}
@Override
protected void onStart() {
super.onStart();
Log.d("lifecycle","onStart invoked");
}
@Override
protected void onResume() {
super.onResume();
Log.d("lifecycle","onResume invoked");
}
@Override
protected void onPause() {
super.onPause();
Log.d("lifecycle","onPause invoked");
}
@Override
protected void onStop() {
super.onStop();
Log.d("lifecycle","onStop invoked");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("lifecycle","onRestart invoked");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("lifecycle","onDestroy invoked");
}
}
ROLE OF THE ANDROID MANIFEST FILE
The AndroidManifest.xml is a configuration file. It is created by ADT when creating a new Android
project and is kept in the project’s root directory. The manifest file presents essential information about your
app to the Android system, information the system must have before it can run any of the app's code.

9
It’s an XML file that defines the overall structure and information about the application for example,
the activities, services, and intents used in the application. It also contains the permissions that the application
might need to run. The manifest also defines metadata of the application such as its icon and label. Besides
this, the file also contains the information required in building and packaging the application for installing and
deploying it on an Android device or the emulator. To sum up, the application manifest file contains all the
essential information required by the Android system to run the application.
The manifest essentially fulfills the following roles:
 It makes key information about the app available without having to read other files in the package or
run the application.
 It defines which components of the application (such as activities and services) will be accessible
externally to other apps, and how those components interact with other apps.
 It unambiguously declares which components and resources (icons, text strings, etc.) to use in which
cases, in particular with relation to other apps.
 It lists the libraries that the application must be linked against.
For example, if your app can accept files shared from other apps, the manifest says which component will
receive the files, and what kind of files it can receive.
The main advantage of this approach is, it puts all of the information in one place, which reduces the chance
of mistakes or human error when a developer is making an app. It is also an extensible system, so other kinds
of data can be added later without breaking existing apps. And being able to read one file to get all the app’s
metadata can help with performance.

Default Code in the Android Manifest File

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidunleashed.welcomemsg"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".WelcomeMsgActivity"
android:label="@string/title_activity_welcome_msg" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
10
</activity>
</application>
</manifest>
The <manifest> tag, is the root element of this XML document and contains several attributes:
• android—Identifies the Android namespace used to provide several system attributes used within the
application.
• package—Its value is set to the application’s Java package. The name of the application package acts as the
unique identifier for the application in the Android device.
• versionCode/versionName—The versionCode attribute is used to define the current application version.
The version is used internally to compare application versions. The versionName attribute is used to specify a
version number that is displayed to users.
• <uses-sdk>—This tag is optional and is used to specify the maximum, minimum, and preferred API level
required for the application to operate. Three attributes are used with this tag as follows:
• android:minSdkVersion—Used to specify the minimum API level required for this application to run. The
default value is “1.” For example, the following attribute says that the minimum API level required by the
application is 15: android:minSdkVersion="15"
Hence, the application will run on API Level 15 and above, but will not run on API Level 14 or below.
• android:targetSdkVersion—Used to specify the preferred API level on which the application is designed to
run.
• android:maxSdkVersion—Used to specify the maximum API level supportable by the application; that is, the
application cannot run on an API level higher than the one specified in this attribute. While installing the
application, the Android system checks the <uses-sdk> attributes defined in the application’s manifest files
and compares it with its own internal API level. The application can be installed only if
 The value of the android:minSdkVersion attribute of the application must be less than or equal to the
system’s API level. If the android:minSdkVersion attribute is not declared, it is assumed that the
application requires API Level 1.
 The value of the android:maxSdkVersion attribute of the application (if it is declared) must be equal to,
or greater than, the system’s API level.
• <application> tag—Nested within <manifest> is <application>, which is the parent of application control
tags. The icon and label attributes of the application tag refer to icon and label resources that will be displayed
in Android devices to represent the application. The term "@drawable/icon" refers to the image
file icon.png in the res/drawablefolder, and "@string/app_name" refers to the control resource with
ID app_name in the strings.xml file that is stored in the res/values folder of the application.
• <activity> tag—Nested within <application> is the <activity> tag, which describes an Activity component.
This tag’s name attribute identifies a class that is an Activity, WelcomeMsgActivity. This name begins with a
period character to show that it’s relative to the com.androidunleashed.welcomemsg package. That is,
the WelcomeMsgActivity is relative to <manifest>’s package value, com.androidunleashed.welcomemsg.
Remember that on creating the new Android project WelcomeMsg, an Activity
named WelcomeMsgActivity was automatically created for us in the specified
package com.androidunleashed.welcomemsg by the ADT.

11
• <intent- filter>—Nested within <activity> is the <intent-filter>. The intents are used to interact with the
applications and services. By default, the intent specifies the action as MAIN and the category as LAUNCHER;
that is, it makes this Activity available from the application launcher, allowing it to launch when the
application starts. Basically, the <intent-filter> tag declares the capabilities of different components through
the nested <action> and <category> tags.
Besides the preceding default tags used in the manifest file, the following are some of the most commonly
used tags:
• <service> tags—Used for declaring services. Services refer to the processes that run in the background
without a user interface. They perform required processing and handle events silently without user
interaction.
• <receiver> tags—Used for declaring broadcast receivers. Broadcast receivers are used to listen and respond
to broadcast announcements. Applications initiate broadcasts for the interested applications when some
event occurs that requires attention; for example, essential information or confirmation is required from the
user before taking some destructive action. An application can have any number of broadcast receivers. A
broadcast receiver responds by taking a specific action.
• <provider> tags—Used for declaring content providers. Content providers provide content, that is, data to
applications. They help in handling, storing, and sharing data such as audio, images, video, and contact lists
with other applications. Android ships with a number of content providers that the applications can use to
access and share data with other applications.
• <uses-permission> tags—Used for declaring the permissions that the application needs.

CREATING THE USER INTERFACE

There are three approaches to creating user interfaces in Android.


1. You can create user interfaces entirely in Java code
2. Entirely in XML
3. Combining both methods (defining the user interface in XML and then referring and modifying it
through Java code).
The third approach, the combined approach, is highly preferred.
The graphical user interface for an Android app is built using a hierarchy of View and ViewGroup objects.
 A View is an interactive UI component (or widget or control), such as button and text field. It controls a
rectangular area on the screen. It is responsible for drawing itself and handling events (such as clicking,
entering texts). Android provides many ready-to-use Views such as TextView, EditText, Button,
RadioButton, etc, in package android.widget. You can also create your custom View by extending
android.view.View.
 A ViewGroup is an invisible container used to layout the View components. Android provides many
ready-to-use ViewGroups such as LinearLayout, RelativeLayout, TableLayout and GridLayout in package
android.widget. You can also create your custom ViewGroup by extending from
android.view.ViewGroup.
Views and ViewGroups are organized in a single tree structure called view-tree. You can create a view-tree
either using programming codes or describing it in a XML layout file.

12
Figure: Illustration of how ViewGroup objects form branches in the layout and contain other View objects.

Example: Program to demonstrate creating a user interface

COMMONLY USED LAYOUTS AND CONTROLS


The views or the controls that we want to display in an application are arranged in an order or
sequence by placing them in the desired layout. The layouts also known as Containers or ViewGroups. These
are used for organizing the views or controls in the required format. Android provides the following layouts
• LinearLayout: In this layout, all elements are arranged in a descending column from top to bottom or left to
right. Each element contains properties to specify how much of the screen space it will consume. Depending
on the orientation parameter, elements are either arranged in row or column format.
• RelativeLayout:In this layout, each child element is laid out in relation to other child elements. That is, a
child element appears in relation to the previous child. Also, the elements are laid out in relation to the
parent.
• AbsoluteLayout: In this layout, each child is given a specific location within the bounds of the parent layout
object. This layout is not suitable for devices with different screen sizes and hence is deprecated.
• FrameLayout: This is a layout used to display a single view. Views added to this are always placed at the top
left of the layout. Any other view that is added to the FrameLayout overlaps the previous view; that is, each
view stacks on top of the previous one.
• TableLayout: In this layout, the screen is assumed to be divided in table rows, and each of the child elements
is arranged in a specific row and column.
• GridLayout: n this layout, child views are arranged in a grid format, that is, in the rows and columns pattern.
The views can be placed at the specified row and column location. Also, more than one view can be placed at
the given row and column position.
The following list highlights some of the controls commonly used in Android applications:
• TextView:A read-only text label. It supports multiline display, string formatting, and automatic word
wrapping.
• EditText: An editable text box that also accepts multiline entry and word-wrapping.
• ListView: A ViewGroup that creates and manages a vertical list of views, displaying them as rows within the
list.

13
• Spinner: A TextView and an associated list of items that allows us to select an item from the list to display in
the text box.
• Button: A standard command button.
• CheckBox: A button allowing a user to select (check) or unselect (uncheck).
• RadioButton: A mutually exclusive button, which, when selected, unselects all other buttons in the group.

EVENT HANDLING
The action of clicking a Button, pressing the Enter key, or performing any action on any control is considered
an event. The reaction to the event, that is, the action to be taken when the event occurs, is called event
handling. To handle an event, you use the listeners that wait for an event occurrence. When an event occurs,
the listeners detect it and direct the program to the appropriate routine.
An event listener is an interface in the View class that contains a single callback method, called an event
occurrence. For example the callback method onClick() is called when the user clicks on a button. For event
handling, the event listener is either implemented in the Activity class or is defined as an anonymous class.
Thereafter, an instance of the implementation is passed to the respective control through the
setOnClickListener() method.
Note: Click is just one type of an event.
There are three ways of event handling:
• Creating an anonymous inner class
• Implementing the OnClickListener interface
• Declaring the event handler in the XML definition of the control

Toast & Custom Toast With Example In Android Studio:


In Android, Toast is used to display information for a period of time. It contains a message to be displayed quickly and
disappears after specified period of time. It does not block the user interaction. Toast is a subclass of Object class. In this
we use two constants for setting the duration for the Toast. Toast notification in android always appears near the
bottom of the screen. We can also create our custom toast by using custom layout(xml file).

Special Note: In Android, Toast is used when we required to notify user about an operation without expecting any user
input. It displays a small popup for message and automatically fades out after timeout.

Important Methods Of Toast:

Let’s we discuss some important methods of Toast that may be called in order to manage the Toast.
1. makeText(Context context, CharSequence text, int duration): This method is used to initiate the Toast. This method
take three parameters:
14
(A) First is for the application Context,(b) Second is text message and (c)last one is duration for the Toast.
Constants of Toast: Below is the constants of Toast that are used for setting the duration for the Toast.
1. LENGTH_LONG: It is used to display the Toast for a long period of time. When we set this duration the Toast will be
displayed for a long duration.
2. LENGTH_SHORT: It is used to display the Toast for short period of time. When we set this duration the Toast will be
displayed for short duration.
Below we show the use of makeText() method of Toast in which we set application context, a text message and duration
for the Toast.
Toast toast = Toast.makeText(getApplicationContext(), "Simple Toast", Toast.LENGTH_LONG); // initiate the Toast with
context, message and duration for the Toast

2. show(): This method is used to display the Toast on the screen. This method is display the text which we create using
makeText() method of Toast.
Below we Firstly initiate the Toast and then display it using show() method.
Toast toast = Toast.makeText(getApplicationContext(), "Simple Toast In Android", Toast.LENGTH_LONG); // initiate the
Toast with context, message and duration for the Toast

toast.show(); // display the Toast

3. setGravity(int,int,int): This method is used to set the gravity for the Toast. This method accepts three parameters:
a Gravity constant, an x-position offset, and a y-position offset.
Below we Firstly initiate the Toast, set top and left gravity and then display it using show() method.
Toast toast = Toast.makeText(getApplicationContext(), "Simple Toast In Android", Toast.LENGTH_LONG); // initiate the
Toast with context, message and duration for the Toast

toast.setGravity(Gravity.TOP | Gravity.LEFT, 0, 0); // set gravity for the Toast.

toast.show(); // display the Toast

4. setText(CharSequence s): This method is used to set the text for the Toast. If we use makeText() method and then we
want to change the text value for the Toast then we use this method.
Below we firstly create a new Toast using makeText() method and then set the text for the Toast.
Toast toast = Toast.makeText(getApplicationContext(), "Simple Toast In Android", Toast.LENGTH_LONG); // initiate the
Toast with context, message and duration for the Toast

toast.setGravity(Gravity.TOP | Gravity.LEFT, 0, 0); // set gravity for the Toast.

toast.setText("Changed Toast Text"); // set the text for the Toast

toast.show(); // display the Toast

5. setDuration(int duration): This method is used to set the duration for the Toast. If we use makeText() method and
then we want to change the duration for the Toast then we use this method.
Below we firstly create a new Toast using makeText() method and then set the duration for the Toast.

15
Toast toast = Toast.makeText(getApplicationContext(), "Simple Toast In Android", Toast.LENGTH_LONG); // initiate the
Toast with context, message and duration for the Toast

toast.setGravity(Gravity.TOP | Gravity.LEFT, 0, 0); // set gravity for the Toast.

toast.setDuration(Toast.LENGTH_SHORT); // set the duration for the Toast.

toast.show(); // display the Toast

6. inflate(int, ViewGroup): This method is used to inflate the layout from the xml. In this method first parameter is the
layout resource ID and the second is the root View.
Below we retrieve the Layout Inflater and then inflate the layout from the xml file.
// Retrieve the Layout Inflater and inflate the layout from xml

LayoutInflater inflater = getLayoutInflater();

View layout = inflater.inflate(R.layout.custom_toast_layout,

(ViewGroup) findViewById(R.id.toast_layout_root));

7. setView(View): This method is used to set the view for the Toast. In this method we pass the inflated layout which we
inflate using inflate() method.
Below we firstly retrieve the layout inflater and then inflate the layout and finally create a new Toast and pass the
inflated layout in the setView() method.
// Retrieve the Layout Inflater and inflate the layout from xml

LayoutInflater inflater = getLayoutInflater();

View layout = inflater.inflate(R.layout.custom_toast_layout,

(ViewGroup) findViewById(R.id.toast_layout_root));

// create a new Toast using context

Toast toast = new Toast(getApplicationContext());

toast.setDuration(Toast.LENGTH_LONG); // set the duration for the Toast

toast.setView(layout); // set the inflated layout

toast.show(); // display the custom Toast

Custom Toast in Android:


In Android, Sometimes simple Toast may not be satisfactory, and then we can go for customizing a Toast. For creating a
custom layout, define a View layout, in XML and pass the root View object to the setView(View) method.

16
Steps for Implementation of Custom Toast In Android:
Step 1: Firstly Retrieve the Layout Inflater with getLayoutInflater() (or getSystemService()) and then inflate the layout
from XML using inflate(int, ViewGroup). In inflate method first parameter is the layout resource ID and the second is the
root View.
Step 2: Create a new Toast with Toast(Context) and set some properties of the Toast, such as the duration and gravity.
Step 3: Call setView(View) and pass the inflated layout in this method.
Step 4: Display the Toast on the screen using show() method of Toast.
In the below example we have shown the functioning of Toast and custom Toast both.
Toast And Custom Toast Example In Android Studio:
Below is the example of Toast and Custom Toast in Android. In this example we display two Button’s one for Simple
Toast and other for Custom Toast and perform click event on them. Whenever a user click on simple Toast Button a
Toast with message “Simple Toast In Android” displayed on the screen and when a user clicks on custom toast Button a
message “Custom Toast In Android” with a image displayed on the screen. For Creating a custom toast we firstly retrieve
the layout inflater and then inflate the custom toast layout from the xml file. After that we get the reference
of TextView and ImageView from the inflated layout and set the text and image in the TextView and ImageView. Finally
we create a new Toast and pass the inflated layout in the setView() method and then display the Toast by using show()
method of Toast.

Creating and Starting an Activity:

How To Create New Activity in Android Studio

We create New Activity in Android Studio to create XML file for designing UI and java file coding.
Below are the steps to create new Activity in Android Studio:

17
How To Create New Activity in Android Studio:
Step 1: Firstly, click on app > res > layout > Right Click on layout. After that Select New > Activity and
choose your Activity as per requirement. Here we choose Blank Activity as shown in figure below.

Step 2: After that Customize the Activity in Android Studio. Enter the “Activity Name” and “Package
name” in the Text box and Click on Finish button.

Step 3: After that your new Activity in Layout will be created. Your XML Code is in Text and your
Design Output is in Design.

18
Using the Edit Text Control:

EditText Tutorial With Example In Android Studio: Input Field


In Android, EditText is a standard entry widget in android apps. It is an overlay over TextView that
configures itself to be editable. EditText is a subclass of TextView with text editing operations. We
often use EditText in our applications in order to provide an input or text field, especially in
forms. The most simple example of EditText is Login or Sign-in form.

Text Fields in Android Studio are basically EditText:

19
Important Note: An EditText is simply a thin extension of a TextView. An EditText inherits all the
properties of a TextView.

EditText Code:
We can create a EditText instance by declaring it inside a layout(XML file) or by instantiating it
programmatically (i.e. in Java Class).
EditText code in XML:
<EditText

android:id="@+id/simpleEditText"

android:layout_height="wrap_content"

android:layout_width="match_parent"/>

Retrieving / Getting the Value From EditText In Java Class:


Below is the example code of EditText in which we retrieve the value from a EditText in Java class. We
have used this code in the example you will find at the end of this post.
EditText simpleEditText = (EditText) findViewById(R.id.simpleEditText);

String editTextValue = simpleEditText.getText().toString();

Attributes of EditText:
Now let’s we discuss few attributes that helps us to configure a EditText in your xml.
1. id: id is an attribute used to uniquely identify a text EditText. Below is the example code in which
we set the id of a edit text.
<EditText

android:id="@+id/simpleEditText"

20
android:layout_height="wrap_content"

android:layout_width="match_parent"/>

2. gravity: The gravity attribute is an optional attribute which is used to control the alignment of the
text like left, right, center, top, bottom, center_vertical, center_horizontal etc.
Below is the example code with explanation included in which we set the right gravity for text of a
EditText.
<EditText

android:id="@+id/simpleEditText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Enter Email"

android:gravity="right"/><!--gravity of a edit text-->

3. text: text attribute is used to set the text in a EditText. We can set the text in xml as well as in
the java class.

Below is the example code in which we set the text “Username” in a edit text.
<EditText

android:id="@+id/simpleEditText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:text="Username"/><!--set text in edit text-->

21
Setting text in EditText In Java class:

Below is the example code in which we set the text in a text view programmatically means in java
class.
EditText editText = (EditText)findViewById(R.id.simpleEditText);

editText.setText("Username");//set the text in edit text

4. hint: hint is an attribute used to set the hint i.e. what you want user to enter in this edit text.
Whenever user start to type in edit text the hint will automatically disappear.
Below is the example code with explanation in which we set the hint of a edit text.
<EditText

android:id="@+id/simpleEditText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:hint="Enter Your Name Here" /><!--display the hint-->

Setting hint in EditText In Java class:

Below is the example code in which we set the text in a text view programmatically means in java
class.
EditText editText = (EditText)findViewById(R.id.simpleEditText);

editText.setHint("Enter Your Name Here");//display the hint


22
5. textColor: textColor attribute is used to set the text color of a text edit text. Color value is in the
form of “#argb”, “#rgb”, “#rrggbb”, or “#aarrggbb”.
Below is the example code with explanation included in which we set the red color for the displayed
text of a edit text.
<EditText

android:id="@+id/simpleEditText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:text="Password"

android:textColor="#f00"/><!--set the red text color-->

Setting textColor in EditText In Java class:


Below is the example code in which we set the text color of a edit text programmatically means in
java class.
EditText simpleEditText=(EditText)findViewById(R.id.simpleEditText);

simpleEditText.setTextColor(Color.RED);//set the red text color

6. textColorHint: textColorHint is an attribute used to set the color of displayed hint.


Below is the example code with explanation included in which we set the green color for displayed
hint of a edit text.
<EditText

android:id="@+id/simpleEditText"

23
android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:hint="Enter Your Name Here"

android:textColorHint="#0f0"/><!--set the hint color green-->

Setting textColorHint in EditText In Java class:


Below is the example code in which we set the hint color of a edit text programmatically means in
java class.
EditText simpleEditText=(EditText)findViewById(R.id.simpleEditText);

simpleEditText.setHintTextColor(Color.green(0));//set the green hint color

7. textSize: textSize attribute is used to set the size of text of a edit text. We can set the text size in
sp(scale independent pixel) or dp(density pixel).
Below is the example code in which we set the 25sp size for the text of a edit text.
<EditText

android:id="@+id/simpleEditText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:text="AbhiAndroid"

android:textSize="25sp" /><!--set 25sp text size-->

Setting textSize in EditText in Java class:


Below is the example code in which we set the text size of a edit text programmatically means in java
class.
EditText simpleEditText=(EditText)findViewById(R.id.simpleEditText);
24
simpleEditText.setTextSize(25);//set size of text

8. textStyle: textStyle attribute is used to set the text style of a edit text. The possible text styles are
bold, italic and normal. If we need to use two or more styles for a edit text then “|” operator is used
for that.
Below is the example code with explanation included, in which we set the bold and italic text styles
for text.
<EditText

android:id="@+id/simpleEditText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:text="Email"

android:textSize="25sp"

android:textStyle="bold|italic"/><!--set bold and italic text style-->

9. background: background attribute is used to set the background of a edit text. We can set a color
or a drawable in the background of a edit text.
25
Below is the example code with explanation included in which we set the black color for the
background, white color for the displayed hint and set 10dp padding from all the side’s for edit text.
<EditText android:id="@+id/simpleEditText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:hint="Enter Your Name Here"

android:padding="15dp"

android:textColorHint="#fff"

android:textStyle="bold|italic"

android:background="#000"/><!--set background color black-->

Setting Background in EditText In Java class:Below is the example code in which we set the
background color of a edit text programmatically means in java class.

EditText simpleEditText=(EditText)findViewById(R.id.simpleEditText);

simpleEditText.setBackgroundColor(Color.BLACK);//set black background color

10. padding: padding attribute is used to set the padding from left, right, top or bottom. In above
example code of background we also set the 10dp padding from all the side’s of edit text.

26
Example I – EditText in Android Studio
Below is the example of edit text in which we get the value from multiple edittexts and
on button click event the Toast will show the data defined in Edittext.
Step 1: Create a new project in Android Studio and name it EditTextExample.
Step 2: Now Open res -> layout -> xml (or) activity_main.xml and add following code. In this code we
have added multiple edittext and a button with onclick functionality.
<?xml version="1.0" encoding="utf-8"?>

<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="com.example.edittextexample.MainActivity">

<EditText

android:id="@+id/editText1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"
27
android:layout_alignParentStart="true"

android:layout_alignParentTop="true"

android:layout_marginLeft="50dp"

android:layout_marginStart="50dp"

android:layout_marginTop="24dp"

android:ems="10"

android:hint="@string/name"

android:inputType="textPersonName"

android:selectAllOnFocus="true" />

<EditText

android:id="@+id/editText2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignLeft="@+id/editText1"

android:layout_alignStart="@+id/editText1"

android:layout_below="@+id/editText1"

android:layout_marginTop="19dp"

android:ems="10"

android:hint="@string/password_0_9"

android:inputType="numberPassword" />

<EditText

android:id="@+id/editText3"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignLeft="@+id/editText2"

android:layout_alignStart="@+id/editText2"

android:layout_below="@+id/editText2"

28
android:layout_marginTop="12dp"

android:ems="10"

android:hint="@string/e_mail"

android:inputType="textEmailAddress" />

<EditText

android:id="@+id/editText4"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignLeft="@+id/editText3"

android:layout_alignStart="@+id/editText3"

android:layout_below="@+id/editText3"

android:layout_marginTop="18dp"

android:ems="10"

android:hint="@string/date"

android:inputType="date" />

<EditText

android:id="@+id/editText5"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignLeft="@+id/editText4"

android:layout_alignStart="@+id/editText4"

android:layout_below="@+id/editText4"

android:layout_marginTop="18dp"

android:ems="10"

android:hint="@string/contact_number"

android:inputType="phone" />

<Button

29
android:id="@+id/button"

style="@android:style/Widget.Button"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:layout_alignParentStart="true"

android:layout_below="@+id/editText5"

android:layout_marginTop="62dp"

android:text="@string/submit"

android:textSize="16sp"

android:textStyle="normal|bold" />

</RelativeLayout>

Step 3: Now open app -> java -> package -> MainActivity.java and add the below code.
In this we just fetch the text from the edittext, further with the button click event a toast will show
the text fetched before.
package com.example.edittextexample;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

Button submit;

EditText name, password, email, contact, date;

@Override

protected void onCreate(Bundle savedInstanceState) {

30
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

name = (EditText) findViewById(R.id.editText1);

password = (EditText) findViewById(R.id.editText2);

email = (EditText) findViewById(R.id.editText3);

date = (EditText) findViewById(R.id.editText4);

contact = (EditText) findViewById(R.id.editText5);

submit = (Button) findViewById(R.id.button);

submit.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if (name.getText().toString().isEmpty() || password.getText().toString().isEmpty() ||
email.getText().toString().isEmpty() || date.getText().toString().isEmpty()

|| contact.getText().toString().isEmpty()) {

Toast.makeText(getApplicationContext(), "Enter the Data", Toast.LENGTH_SHORT).show();

} else {

Toast.makeText(getApplicationContext(), "Name - " + name.getText().toString() + " \n" + "Password - " +


password.getText().toString()

+ " \n" + "E-Mail - " + email.getText().toString() + " \n" + "Date - " + date.getText().toString()

+ " \n" + "Contact - " + contact.getText().toString(), Toast.LENGTH_SHORT).show();

});

31
Output:
Now start the AVD in Emulator and run the App. You will see screen asking you to fill the data in
required fields like name, password(numeric), email, date, contact number. Enter data and click on
button. You will see the data entered will be displayed as Toast on screen.

Example II – EditText in Android Studio


Below is the example of edit text in which we get the value from a edit text on button click event and
then display it in a Toast. Below is the final output and code.

Step 1: Create a new project in Android Studio and name it EditTextExample.

Select File -> New -> New Project and Fill the forms and click "Finish" button.

Step 2: Now Open res -> layout -> xml (or) activity_main.xml and add following code. Here we will
design one EditText for filling name and one Button which will be used to display the name entered by
the user.

32
<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">

<EditText

android:id="@+id/simpleEditText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:background="#F2F2F2"

android:hint="Enter Your Name Here"

android:padding="15dp"

android:textColorHint="#000"

android:textStyle="bold|italic"

android:layout_marginTop="100dp" />

<Button

android:id="@+id/displayText"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:background="#000"

android:padding="10dp"

33
android:text="Display Text"

android:textColor="#0f0"

android:textStyle="bold" />

</RelativeLayout>

Step 3: Now open app -> java -> package -> MainActivity.java and add the below code. The explanation is included in the
code itself as comment.

package example.abhiandriod.edittextexample;

import android.graphics.Color;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

final EditText simpleEditText = (EditText) findViewById(R.id.simpleEditText);//get the id for edit text

Button displayText = (Button) findViewById(R.id.displayText);//get the id for button

displayText.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

if (simpleEditText.getText().toString() != null)//check whether the entered text is not null

{
34
Toast.makeText(getApplicationContext(), simpleEditText.getText().toString(),
Toast.LENGTH_LONG).show();//display the text that you entered in edit text

});

Output:Now start the AVD in Emulator and run the App. You will see screen asking you to fill your
name. Enter your name and click on button. You will see the name entered will be displayed as Toast
on screen.

TextInputLayout / Floating Labels In EditText:


TextInputLayout is a new element introduced in Material Design Support library to display the floating
labelin EditText. Read our advance Floating Labels tutorial to learn how to use it in your App.

35
Choosing Options with Checkbox:
In Android, CheckBox is a type of two state button either unchecked or checked in Android. Or you
can say it is a type of on/off switch that can be toggled by the users. You should use checkbox when
presenting a group of selectable options to users that are not mutually exclusive. CompoundButton is
the parent class of CheckBoxclass.

In android there is a lot of usage of check box. For example, to take survey in Android app we can list
few options and allow user to choose using CheckBox. The user will simply checked these checkboxes
rather than type their own option in EditText. Another very common use of CheckBox is as remember
me option in Login form.

CheckBox code in XML:


<CheckBox

android:id="@+id/simpleCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Simple CheckBox"/>

36
Important Note: You can check the current state of a check box programmatically by using
isChecked() method. This method returns a Boolean value either true or false, if a check box is
checked then it returns true otherwise it returns false. Below is an example code in which we checked
the current state of a check box.

//initiate a check box

CheckBox simpleCheckBox = (CheckBox) findViewById(R.id.simpleCheckBox);

//check current state of a check box (true or false)

Boolean checkBoxState = simpleCheckBox.isChecked();

Attributes of CheckBox:
Now let’s we discuss important attributes that helps us to configure a check box in XML file (layout).
1.id: id is an attribute used to uniquely identify a check box. Below we set the id of a image button.
<CheckBox

android:id="@+id/simpleCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Simple CheckBox"/>

2. checked: checked is an attribute of check box used to set the current state of a check box. The
value should be true or false where true shows the checked state and false shows unchecked state of
a check box. The default value of checked attribute is false. We can also set the current state
programmatically.
Below is an example code in which we set true value for checked attribute that sets the current state
to checked.
<CheckBox

android:id="@+id/simpleCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Simple CheckBox"

android:checked="true"/> <!--set the current state of the check box-->

37
Setting Current State Of CheckBox In Java Class:

Below we set the current state of CheckBox in java class.


/*Add in Oncreate() funtion after setContentView()*/

// initiate a check box

CheckBox simpleCheckBox = (CheckBox) findViewById(R.id.simpleCheckBox);

// set the current state of a check box

simpleCheckBox.setChecked(true);

3. gravity: The gravity attribute is an optional attribute which is used to control the alignment of the
text in CheckBox like left, right, center, top, bottom, center_vertical, center_horizontal etc.
Below we set the right and center_vertical gravity for the text of a check box.
<CheckBox android:id="@+id/simpleCheckBox"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Simple CheckBox"

android:checked="true"

android:gravity="right|center_vertical"/> <!-- gravity of the check box-->

38
4. text: text attribute is used to set the text in a check box. We can set the text in xml as well as in
the javaclass.

Below is the example code with explanation included in which we set the text “Text Attribute Of
Check Box” for a check box.
<CheckBox

android:id="@+id/simpleCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:checked="true"

android:text="Text Attribute Of Check Box"/> <!--displayed text of the check box-->

Setting text in CheckBox In Java class:

Below is the example code in which we set the text of a check box programmatically means
in java class.
/*Add in Oncreate() funtion after setContentView()*/

// initiate check box

CheckBox simpleCheckBox = (CheckBox) findViewById(R.id.simpleCheckBox);

// displayed text of the check box

simpleCheckBox.setText("Text Attribute Of Check Box");

5. textColor: textColor attribute is used to set the text color of a check box. Color value is in form of
“#argb”, “#rgb”, “#rrggbb”, or “#aarrggbb”.
Below we set the red color for the displayed text of a check box.
<CheckBox

android:id="@+id/simpleCheckBox"
39
android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Text is Red Color"

android:textColor="#f00"

android:checked="true"/> <!-- red color for the text of check box-->

Setting textColor in CheckBox In Java class:


Below we set the text color of a check box programmatically.
/*Add in Oncreate() funtion after setContentView()*/

//initiate the checkbox

CheckBox simpleCheckBox = (CheckBox) findViewById(R.id.simpleCheckBox);

//red color for displayed text

simpleCheckBox.setTextColor(Color.RED);

6. textSize: textSize attribute is used to set the size of text of a check box. We can set the text size in
sp(scale independent pixel) or dp(density pixel).
Below is the example code in which we set the 20sp size for the text of a check box.
<CheckBox

android:id="@+id/simpleCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Text size Attribute Of Check Box"

android:textColor="#00f"

android:checked="false"

40
android:textSize="20sp"/><!--set Text Size of text in CheckBox-->

Setting Text Size in CheckBox In Java class:

Below we set the text size of a check box in java class.


/*Add in Oncreate() funtion after setContentView()*/

CheckBox simpleCheckBox = (CheckBox) findViewById(R.id.simpleCheckBox);

//set 20sp displayed text size

simpleCheckBox.setTextSize(20);

7. textStyle: textStyle attribute is used to set the text style of the text of a check box. The possible
text styles are bold, italic and normal. If we need to use two or more styles for a text view then “|”
operator is used for that.
Below we set the bold and italic text styles for text of a check box.
<Check Box android:id="@+id/simpleCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Style Attribute Of Check Box"
android:textColor="#44f"
android:textSize="20sp"
android:checked="false"
android:textStyle="bold|italic"/>

41
8. background: background attribute is used to set the background of a check box. We can set a color
or a drawable in the background of a check box.
Below we set the black color for the background, white color for the displayed text of a check box.
<Check Box

android:id="@+id/simpleCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Text size Attribute Of Check Box"

android:textColor="#fff"

android:textSize="20sp"

android:textStyle="bold|italic"

android:checked="true"

android:background="#000" /><!-- black background for the background of check box-->

Setting Background in CheckBox In Java class:


Below is the example code in which we set the background color of a check box programmatically
means in java class.
/*Add in Oncreate() funtion after setContentView()*/

CheckBox simpleCheckBox = (CheckBox) findViewById(R.id.simpleCheckBox);

// set background in CheckBox

simpleCheckBox.setBackgroundColor(Color.BLACK);

9. padding: padding attribute is used to set the padding from left, right, top or bottom.

 paddingRight :set the padding from the right side of the check box.
 paddingLeft :set the padding from the left side of the check box.
 paddingTop :set the padding from the top side of the check box.
42
 paddingBottom :set the padding from the bottom side of the check box.
 Padding :set the padding from the all side’s of the check box.

Below is the example code of padding where we set the 30dp padding from all the side’s of the check
box.
<Check Box android:id="@+id/simpleCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Padding Attribute Of Check Box"

android:textColor="#44f"

android:textSize="20sp"

android:textStyle="bold|italic"

android:checked="false"

android:padding="30dp"/> <!--30dp padding from all side’s-->

Example of CheckBox In Android Studio:


Below is the example of CheckBox in Android, in which we display five check boxes using background
and other attributes we discusses earlier in this post. Every check box represents a different subject
name and whenever you click on a check box then text of that checked check box is displayed in a
toast. Below is the final output, code and step by step explanation of the example:

43
Step 1: Create a new project and name it CheckBoxExample

In this step we create a new project in android studio by filling all the necessary details of the app like
app name, package name, api versions etc.

Select File -> New -> New Project and Fill the forms and click "Finish" button.

Step 2: Now Open res -> layout -> activity_main.xml (or) main.xml and add the following code:
In this step we open an xml file and add the code for displaying five one TextView and check boxes.
<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">

<Text View

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Select Your Programming language: "

android:textColor="#f00"

android:textSize="20sp"

android:textStyle="bold" />

<Linear Layout

android:id="@+id/linearLayout"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_marginTop="30dp"

44
android:background="#e0e0e0"

android:orientation="vertical">

<Check Box

android:id="@+id/androidCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:checked="false"

android:padding="20dp"

android:text="@string/android"

android:textColor="#44f"

android:textSize="20sp"

android:textStyle="bold|italic" />

<Check Box

android:id="@+id/javaCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:checked="false"

android:padding="20dp"

android:text="@string/java"

android:textColor="#f44"

android:textSize="20sp"

android:textStyle="bold|italic" />

<Check Box

android:id="@+id/phpCheckBox"

android:layout_width="wrap_content"

45
android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:checked="false"

android:padding="20dp"

android:text="@string/php"

android:textColor="#444"

android:textSize="20sp"

android:textStyle="bold|italic" />

<Check Box

android:id="@+id/pythonCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:checked="false"

android:padding="20dp"

android:text="@string/python"

android:textColor="#888"

android:textSize="20sp"

android:textStyle="bold|italic" />

<Check Box

android:id="@+id/unityCheckBox"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:checked="false"

android:padding="20dp"

android:text="@string/unity"

46
android:textColor="#101010"

android:textSize="20sp"

android:textStyle="bold|italic" />

</LinearLayout>

</RelativeLayout>

Step 3: Now Open app -> java-> package -> MainActivity.java


In this step we add the code to initiate the check boxes we created. And then we perform click event
on buttonand display the text for selected check boxes using a toast.
package example.abhiandriod.checkboxexample;

import android.graphics.Color;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.CheckBox;

import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

CheckBox android, java, python, php, unity3D;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// initiate views

android = (CheckBox) findViewById(R.id.androidCheckBox);

android.setOnClickListener(this);

java = (CheckBox) findViewById(R.id.javaCheckBox);


47
java.setOnClickListener(this);

python = (CheckBox) findViewById(R.id.pythonCheckBox);

python.setOnClickListener(this);

php = (CheckBox) findViewById(R.id.phpCheckBox);

php.setOnClickListener(this);

unity3D = (CheckBox) findViewById(R.id.unityCheckBox);

unity3D.setOnClickListener(this);

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.androidCheckBox:

if (android.isChecked())

Toast.makeText(getApplicationContext(), "Android", Toast.LENGTH_LONG).show();

break;

case R.id.javaCheckBox:

if (java.isChecked())

Toast.makeText(getApplicationContext(), "Java", Toast.LENGTH_LONG).show();

break;

case R.id.phpCheckBox:

if (php.isChecked())

Toast.makeText(getApplicationContext(), "PHP", Toast.LENGTH_LONG).show();

break;

case R.id.pythonCheckBox:

if (python.isChecked())

Toast.makeText(getApplicationContext(), "Python", Toast.LENGTH_LONG).show();

break;

48
case R.id.unityCheckBox:

if (unity3D.isChecked())

Toast.makeText(getApplicationContext(), "Unity 3D", Toast.LENGTH_LONG).show();

break;

Step 5: Open res ->values -> strings.xml


In this step we show string file which is used to store string data of an app.
<resources>

<string name="app_name">CheckBoxExample</string>

<string name="hello_world">Hello world!</string>

<string name="action_settings">Settings</string>

<string name="android">Android</string>

<string name="java">Java</string>

<string name="php">PHP</string>

<string name="python" >Python</string>

<string name="unity">Unity 3D</string>

</resources>

Output: Now start the AVD in Emulator and run the App. You will see 5 checkbox option asking you to
choose your programming language. Select and the text of that particular CheckBox will appear on
Screen.

49
Choosing Mutually Exclusive Items Using Radio Buttons:

In Android, RadioButton are mainly used together in a RadioGroup. In RadioGroup checking the one
radio button out of several radio button added in it will automatically unchecked all the others. It
means at one time we can checked only one radio button from a group of radio buttons which belong
to same radio group. The most common use of radio button is in Quiz App.

RadioButon is a two state button that can be checked or unchecked. If a radio button is unchecked
then a user can check it by simply clicking on it. Once a RadiaButton is checked by user it can’t be
unchecked by simply pressing on the same button. It will automatically unchecked when you press
any other RadioButton within same RadioGroup.

Important Note: RadioGroup is a widget used in Android for the grouping of radio buttons and
provide the feature of selecting only one radio button from the set. When a user try to select any
other radio button within same radio group the previously selected radio button will be automatically
unchecked.
Radio Group And Radio Button code in XML:

<Radio Group
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Radio Button
android:id="@+id/simpleRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Radio Button
android:id="@+id/simpleRadioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</Radio Group>

50
Checking Current State Of Radio Button:

You can check the current state of a radio button programmatically by using isChecked() method. This method returns a
Boolean value either true or false. if it is checked then returns true otherwise returns false. Below is an example code
with explanation in which we checked the current state of a radio button.

/*Add in Oncreate() funtion after setContentView()*/

RadioButton simpleRadioButton = (RadioButton) findViewById(R.id.simpleRadioButton); // initiate a radio button

Boolean RadioButtonState = simpleRadioButton.isChecked(); // check current state of a radio button (true or false).

Table Of Contents :

1 Attributes of RadioButton In Android:

2 Example Of RadioButton And RadioGroup in Android Studio:

Attributes of RadioButton In Android:

Now let’s we discuss important attributes that helps us to create a beautiful radio button in xml file (layout).

1. id: id is an attribute used to uniquely identify a radio button.

<Radio Button

android:id="@+id/simpleRadioButton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

2. checked: checked attribute in radio button is used to set the current state of a radio button. We can set it either true
or false where true shows the checked state and false shows unchecked state of a radio button. As usual default value of
checked attribute is false. We can also set the current state in JAVA.

Below we set true value for checked attribute which sets the current state to checked of a Button

<Radio Button
android:id="@+id/simpleRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"/> <!-- set the current state of the radio button-->
51
Setting checked State Of RadioButton In Java Class:
Below code set the current state of RadioButton to checked programmatically.

/*Add in Oncreate() funtion after setContentView()*/

// initiate a radio button

RadioButton simpleRadioButton = (RadioButton) findViewById(R.id.simpleRadioButton);

// set the current state of a radio button

simpleRadioButton.setChecked(true);

3. text: text attribute is used to set the text in a radio button. We can set the text both ways either in XML or
in JAVA class.

Below is the example code with explanation included in which we set the text “I am a radiobutton” of a radio button.

<RadioButton

android:id="@+id/simpleRadioButton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:checked="true"

android:layout_centerHorizontal="true"

android:text="I am a radiobutton" /> <!-- displayed text of radio button-->

Setting text of RadioButton In Java class:

Below we set the text of a radio button programmatically:

/*Add in Oncreate() funtion after setContentView()*/

RadioButton simpleRadioButton=(RadioButton) findViewById(R.id.simpleRadioButton);

simpleRadioButton.setText("I am a radiobutton"); // displayed text of radio button

52
4. gravity: The gravity attribute is an optional attribute which is used to control the alignment of text like left, right,
center, top, bottom, center_vertical, center_horizontal etc.

Below is the example code with explanation included in which we set the center gravity for the text of a radio button.

<Radio Button

android:id="@+id/simpleRadioButton"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:checked="true"

android:text="I am a Button"

android:gravity="center"/> <!-- center gravity of the text-->

5. textColor: textColor attribute is used to set the text color of a radio button. Color value is in the form of “#argb”,
“#rgb”, “#rrggbb”, or “#aarrggbb”.

Below we set the red color for the displayed text of a radio button.

<Radio Button

android:id="@+id/simpleRadioButton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:checked="true"

android:layout_centerHorizontal="true"
53
android:text="Male"

android:textColor="#f00" /><!--red color for displayed text-->

Setting text Color of Radio Button text In Java class:

Below we set the text color of a radio button programmatically.

/*Add in Oncreate() funtion after setContentView()*/

RadioButton simpleRadioButton = (RadioButton) findViewById(R.id.simpleRadioButton);// initiate radio button

simpleRadioButton.setTextColor(Color.RED); //red color for displayed text of radio button

6. text Size: text Size attribute is used to set the size of the text of a radio button. We can set the text size in sp(scale
independent pixel) or dp(density pixel).

Below we set the 25sp size for the text of a radio button.

<RadioButton
android:id="@+id/simpleRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:layout_centerHorizontal="true"
android:text="AbhiAndroid"
android:textColor="#f00"
android:textSize="25sp"/> <!--setting text size-->

54
Setting textSize Of RadioButton Text In Java class:

Below we set the text size of a radio button programmatically:

/*Add in Oncreate() funtion after setContentView()*/

RadioButton simpleRadioButton = (RadioButton) findViewById(R.id.simpleRadioButton); // initiate radio button

simpleRadioButton.setTextSize(25); // set 25sp displayed text size of radio button

7. textStyle: textStyle attribute is used to set the text style of the text of a radio button. The possible text styles are
bold, italic and normal. If we need to use two or more styles for a text view then “|” operator is used for that.

Below is the example code with explanation included in which we set the bold and italic text styles for text of a radio
button.

<Radio Button
android:id="@+id/simpleRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:textSize="25sp"
android:layout_centerHorizontal="true"
android:text="Male"
android:textColor="#f00"
android:textStyle="bold|italic"/> <!-- bold and italic text style-->

8. background: background attribute is used to set the background of a radio button. We can set a color or a drawable
in the background of a radio button.

Below we set the black color for the background and red color for the displayed text of a radio button.

<RadioButton

android:id="@+id/simpleRadioButton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:checked="true"

android:textSize="25sp"

android:textStyle="bold|italic"
55
android:padding="20dp"

android:layout_centerHorizontal="true"

android:text="Male"

android:textColor="#f00"

android:background="#000"/> <!-- black background for radio button-->

Setting Background Of RadioButton In Java class:

Below we set the background color of a radio button programmatically.

/*Add in Oncreate() funtion after setContentView()*/

RadioButton simpleRadioButton = (RadioButton) findViewById(R.id.simpleRadioButton);

simpleRadioButton.setBackgroundColor(Color.BLACK);

9. padding: padding attribute is used to set the padding from left, right, top or bottom.

paddingRight: set the padding from the right side of the radio button.

paddingLeft : set the padding from the left side of the radio button.

paddingTop : set the padding from the top side of the radio button.

paddingBottom: set the padding from the bottom side of the radio button.

Padding: set the padding from the all side’s of the radio button.

Below we set padding attribute of 20dp padding from all the side’s of the radio button.

<Radio Button

android:id="@+id/simpleRadioButton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:checked="true"

android:textSize="25sp"

android:textStyle="bold|italic"
56
android:layout_centerHorizontal="true"

android:text="AbhiAndroid"

android:textColor="#f00"

android:padding="40dp"/> <!--40dp padding from all the sides of radio button-->

10. drawableBottom, drawableTop, drawableLeft And drawableRight: These attribute draw the drawable to the
below of the text of RadioButton.

Below we set the icon to the right of the text of a RadioButton.

<RadioButton
android:id="@+id/simpleRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:textSize="25sp"
android:padding="20dp"
android:layout_centerHorizontal="true"
android:text="AbhiAndroid"
android:textColor="#f00"
android:drawableRight="@drawable/ic_launcher" /> <!-- drawable icon at the right of radio button-->

Example Of RadioButton And RadioGroup in Android Studio:

Below is the example of Radiobutton in Android where we display five radio buttons with background and other
attributes. The radio buttons are used to select your favorite WWE superstar with one “submit” button. Below is the
final output, download code and step by step explanation of tutorial:

57
Step 1: Create a new project and name it Radio Button Example
Select File -> New -> New Project and Fill the forms and click “Finish” button.
Step 2: Open res -> layout -> activity_main.xml (or) main.xml and add following code:
In this step we open an xml file and add the code for displaying 5 Radio Button and one normal button.
<Linear Layout 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">
<Linear Layout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#e0e0e0"
android:orientation="vertical">

<Text View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Select your favourite wwe SuperStar :: "
android:textColor="#000"
android:textSize="20sp"
android:textStyle="bold" />
<Radio Group
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Radio Button
android:id="@+id/johnCena"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
58
android:layout_marginTop="10dp"
android:checked="true"
android:text="@string/johnCena"
android:textColor="#154"
android:textSize="20sp"
android:textStyle="bold" />
<Radio Button
android:id="@+id/randyOrton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:checked="false"
android:text="@string/randyOrton"
android:textColor="#154"
android:textSize="20sp"
android:textStyle="bold" />
<Radio Button
android:id="@+id/romanReigns"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:checked="false"
android:text="@string/romanReigns"
android:textColor="#154"
android:textSize="20sp"
android:textStyle="bold" />
<Radio Button
android:id="@+id/goldBerg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:checked="false"
android:text="@string/goldBerg"
android:textColor="#154"
android:textSize="20sp"
android:textStyle="bold" />
<Radio Button
android:id="@+id/sheamus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:checked="false"
android:text="@string/sheamus"
android:textColor="#154"
android:textSize="20sp"
android:textStyle="bold" />
</RadioGroup>
59
<Button
android:id="@+id/submitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="20dp"
android:background="#0f0"
android:padding="10dp"
android:text="Submit"
android:textColor="#fff"
android:textSize="20sp"
android:textStyle="bold" />
</Linear Layout>
</LinearLayout>
Step 3: Open src -> package -> MainActivity.java
In this step we open MainActivity and add the code to initiate the RadioButton and normal button. We also perform
click event on button and display the selected superstar’s name by using a Toast.
package example.gb.radiobuttonexample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
RadioButton johnCena, randyOrton, goldBerg, romanReigns, sheamus;
String selectedSuperStar;
Button submit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
johnCena = (RadioButton) findViewById(R.id.johnCena);
randyOrton = (RadioButton) findViewById(R.id.randyOrton);
goldBerg = (RadioButton) findViewById(R.id.goldBerg);
romanReigns = (RadioButton) findViewById(R.id.romanReigns);
sheamus = (RadioButton) findViewById(R.id.sheamus);
submit = (Button) findViewById(R.id.submitButton);
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (randyOrton.isChecked()) {
selectedSuperStar = randyOrton.getText().toString();
} else if (sheamus.isChecked()) {
selectedSuperStar = sheamus.getText().toString();
} else if (johnCena.isChecked()) {
selectedSuperStar = johnCena.getText().toString();
} else if (romanReigns.isChecked()) {
selectedSuperStar = romanReigns.getText().toString();
} else if (goldBerg.isChecked()) {
selectedSuperStar = goldBerg.getText().toString();
60
}
Toast.makeText(getApplicationContext(), selectedSuperStar, Toast.LENGTH_LONG).show(); // print the value of
selected super star
}
});
}
}
Step 4: Open res -> values -> strings.xml
In this step we open String file which is used to store string data of the app.
<resources>
<string name="app_name">RadioButtonExample</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="randyOrton">Randy Orton</string>
<string name="johnCena">John Cena</string>
<string name="romanReigns">Roman Reigns</string>
<string name="goldBerg">Gold Berg</string>
<string name="sheamus">Sheamus</string>
</resources>
Run The App:

Now run the App in Emulator and you will see 5 RadioButton in RadioGroup listing WWE superstar name. Now choose
your favorite one and click on Submit Button. The name will be displayed on Screen.

61
3 CHAPTER IN THIS CHAPTER
▶ Introduction to Layouts
Laying Out Controls in ▶ LinearLayout
Containers ▶ Applying the Orientation
Attribute
▶ Applying Height and Width
Attributes
A container is a view used to contain other views. ▶ Applying the Padding Attribute
Android offers a collection of view classes that act as
▶ Applying the Weight attribute
containers for views. These container classes are called
layouts, and as the name suggests, they decide the organi- ▶ Applying the Gravity Attribute
zation, size, and position of their children views. ▶ Using the android:layout_
Let’s start the chapter with an introduction to different gravity Attribute
layouts used in Android applications. ▶ RelativeLayout

▶ Relative Layout Control


Introduction to Layouts Attributes

Layouts are basically containers for other items known as ▶ AbsoluteLayout


Views, which are displayed on the screen. Layouts help ▶ FrameLayout
manage and arrange views as well. Layouts are defined in
the form of XML files that cannot be changed by our code ▶ TableLayout
during runtime. ▶ TableLayout Operations

Table 3.1 shows the layout managers provided by the ▶ GridLayout


Android SDK.
▶ Screen Orientation
Adaptations
TABLE 3.1 Android Layout Managers

Layout Manager Description


LinearLayout Organizes its children either horizontally
or vertically
RelativeLayout Organizes its children relative to one
another or to the parent
AbsoluteLayout Each child control is given a specific
location within the bounds of the
container
102 CHAPTER 3 Laying Out Controls in Containers

Layout Manager Description


FrameLayout Displays a single view; that is, the next
view replaces the previous view and
hence is used to dynamically change the
children in the layout
TableLayout Organizes its children in tabular form
GridLayout Organizes its children in grid format

The containers or layouts listed in Table 3.1 are also known as ViewGroups as one or
more Views are grouped and arranged in a desired manner through them. Besides the
ViewGroups shown here Android supports one more ViewGroup known as ScrollView,
which is discussed in Chapter 4, “Utilizing Resources and Media.”

LinearLayout
The LinearLayout is the most basic layout, and it arranges its elements sequentially, either
horizontally or vertically. To arrange controls within a linear layout, the following attri-
butes are used:

▶ android:orientation—Used for arranging the controls in the container in horizon-


tal or vertical order

▶ android:layout_width—Used for defining the width of a control

▶ android:layout_height—Used for defining the height of a control

▶ android:padding—Used for increasing the whitespace between the boundaries of the


control and its actual content

▶ android:layout_weight—Used for shrinking or expanding the size of the control to


consume the extra space relative to the other controls in the container

▶ android:gravity—Used for aligning content within a control

▶ android:layout_gravity—Used for aligning the control within the container

Applying the orientation Attribute


The orientation attribute is used to arrange its children either in horizontal or verti-
cal order. The valid values for this attribute are horizontal and vertical. If the value of
the android:orientation attribute is set to vertical, the children in the linear layout
are arranged in a column layout, one below the other. Similarly, if the value of the
android:orientation attribute is set to horizontal, the controls in the linear layout
are arranged in a row format, side by side. The orientation can be modified at runtime
through the setOrientation() method. That is, by supplying the values HORIZONTAL
or VERTICAL to the setOrientation() method, we can arrange the children of the
LinearLayout in row or column format, respectively.
LinearLayout 103

Applying the height and width Attributes


The default height and width of a control are decided on the basis of the text or content
that is displayed through it. To specify a certain height and width to the control, we use
the android:layout_width and android:layout_height attributes. We can specify the
values for the height and width attributes in the following three ways:

▶ By supplying specific dimension values for the control in terms of px (pixels), dip/
dp (device independent pixels), sp (scaled pixels), pts (points), in (inches), and mm
(millimeters). For example, the android:layout_width="20px" attribute sets the
width of the control to 20 pixels.

3
▶ By providing the value as wrap_content. When assigned to the control’s height or
width, this attribute resizes the control to expand to fit its contents. For example,
when this value is applied to the width of the TextView, it expands so that its
complete text is visible.

▶ By providing the value as match_parent. When assigned to the control’s height or


width, this attribute forces the size of the control to expand to fill up all the avail-
able space of the enclosing container.

NOTE
For layout elements, the value wrap_content resizes the layout to fit the controls added
as its children. The value match_parent makes the layout expand to take up all the
space in the parent layout.

Applying the padding Attribute


The padding attribute is used to increase the whitespace between the boundaries of
the control and its actual content. Through the android:padding attribute, we can
set the same amount of padding or spacing on all four sides of the control. Similarly,
by using the android:paddingLeft, android:paddingRight, android:paddingTop, and
android:paddingBottom attributes, we can specify the individual spacing on the left, right,
top, and bottom of the control, respectively.

The following example sets the spacing on all four sides of the control to 5 pixels:

android:padding="5dip"

Similarly, the following example sets the spacing on the left side of the control to 5 pixels:

android:paddingLeft="5dip"

NOTE
To set the padding at runtime, we can call the setPadding() method.
104 CHAPTER 3 Laying Out Controls in Containers

Let’s see how the controls are laid out in the LinearLayout layout using an example.
Create a new Android Project called LinearLayoutApp. The original default content of the
layout file activity_linear_layout_app.xml appears as shown in Listing 3.1.

LISTING 3.1 Default Code in the Layout File activity_linear_layout_app.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" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world"
tools:context=".LinearLayoutAppActivity" />
</RelativeLayout>

Let’s apply the LinearLayout and add three Button controls to the layout. Modify the
activity_linear_layout_app.xml to appear as shown in Listing 3.2.

LISTING 3.2 The activity_linear_layout_app.xml File on Adding Three Button Controls


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/Apple"
android:text="Apple"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/Mango"
android:text="Mango"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/Banana"
android:text="Banana"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
LinearLayout 105

The orientation of LinearLayout is set to vertical, declaring that we want to arrange its
child elements vertically, one below the other. The height and width of the layout are set
to expand to fill up all the available space of the enclosing container, that is, the device
screen. Three Button controls are added to the layout, which appear one below the other.
The IDs and text assigned to the three Button controls are Apple, Mango, and Banana,
respectively. The height of the three controls is set to wrap_content, which is enough
to accommodate the text. Finally, the width of the three controls is set to match_parent,
so that the width of the three controls expands to fill up the available space of the
LinearLayout container. We see the output shown in Figure 3.1.

3
FIGURE 3.1 Three Button controls arranged vertically in LinearLayout

To see the controls appear horizontally, set the orientation attribute of the LinearLayout
to horizontal. We also need to set the layout_width attribute of the three controls to
wrap_content; otherwise, we will be able to see only the first Button control, the one with
the Apple ID. If the layout_width attribute of any control is set to match_parent, it takes
up all the available space of the container, hiding the rest of the controls behind it. By
setting the values of the layout_width attributes to wrap_content, we make sure that the
width of the control expands just to fit its content and does not take up all the available
space. Let’s modify the activity_linear_layout_app.xml to appear as shown in List-
ing 3.3.

LISTING 3.3 The activity_linear_layout_app.xml File on Setting Horizontal Orientation to


the Button Controls
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/Apple"
android:text="Apple"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
106 CHAPTER 3 Laying Out Controls in Containers

<Button
android:id="@+id/Mango"
android:text="Mango"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/Banana"
android:text="Banana"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

The controls are arranged horizontally, as shown in Figure 3.2.

FIGURE 3.2 Three Button controls arranged horizontally in LinearLayout

Applying the weight Attribute


The weight attribute affects the size of the control. That is, we use weight to assign the
capability to expand or shrink and consume extra space relative to the other controls in
the container. The values of the weight attribute range from 0.0 to 1.0, where 1.0 is the
highest value. Let’s suppose a container has two controls and one of them is assigned the
weight of 1. In that case, the control assigned the weight of 1 consumes all the empty
space in the container, whereas the other control remains at its current size. If we assign a
weight of 0.0 to both the controls, nothing happens and the controls maintain their orig-
inal size. If both the attributes are assigned the same value above 0.0, both the controls
consume the extra space equally. Hence, weight lets us apply a size expansion ratio to
the controls. To make the middle Button control, Mango, take up all the available space of
the container, let’s assign a weight attribute to the three controls. Modify the activity_
linear_layout_app.xml file to appear as shown in Listing 3.4.
LinearLayout 107

LISTING 3.4 The activity_linear_layout_app.xml File on Applying the weight Attribute to


the Button Controls
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/Apple"
android:text="Apple"
android:layout_width="wrap_content"

3
android:layout_height="wrap_content"
android:layout_weight="0.0" />
<Button
android:id="@+id/Mango"
android:text="Mango"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.0" />
<Button
android:id="@+id/Banana"
android:text="Banana"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.0" />
</LinearLayout>

By setting the layout_weight attributes of Apple, Mango, and Banana to 0.0, 1.0, and 0.0,
respectively, we allow the Mango button control to take up all the available space of the
container, as shown in Figure 3.3 (left). If we set the value of layout_weight of the Banana
button control to 1.0 and that of Mango back to 0.0, then all the available space of the
container is consumed by the Banana button control, as shown in Figure 3.3 (middle).
Similarly if we set the layout_weight of all controls to 1.0, the entire container space will
be equally consumed by the three controls, as shown in Figure 3.3 (right).

FIGURE 3.3 (left) The weight attribute of the Mango Button control set to 1.0, (middle) the
weight attribute of the Banana Button control set to 1.0, and (right) all three Button controls
set to the same weight attribute

Similarly if we set the weight of Apple, Mango, and Banana to 0.0, 1.0, and 0.5, respec-
tively, we get the output shown in Figure 3.4.
108 CHAPTER 3 Laying Out Controls in Containers

FIGURE 3.4 The weight attribute of the Apple, Mango, and Banana Button controls set to
0.0, 1.0, and 0.5

We can see that the text of the three controls is center-aligned. To align the content of a
control, we use the Gravity attribute.

Applying the Gravity Attribute


The Gravity attribute is for aligning the content within a control. For example, to align
the text of a control to the center, we set the value of its android:gravity attribute to
center. The valid options for android:gravity include left, center, right, top, bottom,
center_horizontal, center_vertical, fill_horizontal, and fill_vertical. The task
performed by few of the said options is as follows:

▶ center_vertical—Places the object in the vertical center of its container, without


changing its size

▶ fill_vertical—Grows the vertical size of the object, if needed, so it completely fills


its container

▶ center_horizontal—Places the object in the horizontal center of its container,


without changing its size

▶ fill_horizontal—Grows the horizontal size of the object, if needed, so it


completely fills its container

▶ center—Places the object in the center of its container in both the vertical and hori-
zontal axis, without changing its size

We can make the text of a control appear at the center by using the android:gravity
attribute, as shown in this example:

android:gravity="center"

We can also combine two or more values of any attribute using the | operator. The follow-
ing example centrally aligns the text horizontally and vertically within a control:

android:gravity="center_horizontal|center_vertical"

Figure 3.5 shows the android:gravity attribute set to left and right for the Button
controls Mango and Banana.
LinearLayout 109

FIGURE 3.5 The text in the Mango and Banana Button controls aligned to the left and right,

3
respectively, through the android:gravity attribute

Besides the android:gravity attribute, Android provides one more similar attribute,
android:layout_gravity. Let’s explore the difference between the two.

Using the android:layout_gravity Attribute


Where android:gravity is a setting used by the View, the android:layout_gravity is used
by the container. That is, this attribute is used to align the control within the container.
For example, to align the text within a Button control, we use the android:gravity attri-
bute; to align the Button control itself in the LinearLayout (the container), we use the
android:layout_gravity attribute. Let’s add the android:layout_gravity attribute to
align the Button controls themselves. To see the impact of using the android:layout_
gravity attribute to align the Button controls in the LinearLayout, let’s first arrange them
vertically. So, let’s modify activity_linear_layout_app.xml to make the Button controls
appear vertically, one below the other as shown in Listing 3.5.

LISTING 3.5 The activity_linear_layout_app.xml File on Arranging the Button Controls


Vertically
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/Apple"
android:text="Apple"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/Mango"
android:text="Mango"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/Banana"
android:text="Banana"
110 CHAPTER 3 Laying Out Controls in Containers

android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

The preceding code arranges the Button controls vertically, as shown in Figure 3.6 (left).
To align the Button controls Mango and Banana to the center and to the right of the
LinearLayout container, add the following statements to the respective tags in the activ-
ity_linear_layout_app.xml layout file:

android:layout_gravity="center"

and
android:layout_gravity="right"

The two Button controls, Mango and Banana, are aligned at the center and to the right in
the container, as shown in Figure 3.6 (middle).

FIGURE 3.6 (left) The three Button controls vertically aligned with the width attribute set to
wrap_content, (middle) the Mango and Banana Button controls aligned to the center and right
of container, and (right) the width of the three Button controls expanded to take up all the avail-
able space

At the moment, the layout_width attribute of the three controls is set to wrap_content.
The width of the three controls is just enough to accommodate their content. If we now
set the value of the android:layout_width attribute for all three controls to match_parent,
we find that all three Button controls expand in width to take up all the available space
of the container, as shown in Figure 3.6 (right). Now we can apply the android:gravity
attribute to align the text within the controls. Let’s add the following three attributes to
the Button controls Apple, Mango, and Banana:

android:gravity="left"
android:gravity="center"

and

android:gravity="right"

These lines of code align the content of the three Button controls to the left, to the
center, and to the right within the control, as shown in Figure 3.7 (left). Because
the three Button controls are arranged vertically in the layout (the orientation of the
LinearLayout is set to vertical), the application of the weight attribute makes the controls
RelativeLayout 111

expand vertically instead of horizontally as we saw earlier. To see the effect, let’s add the
following statement to the tags of all three Button controls:

android:layout_weight="0.0"

As expected, there will be no change in the height of any control, as the weight value
assigned is 0.0. Setting an equal value above 0.0 for all three controls results in equal
division of empty space among them. For example, assigning the android:layout_
weight="1.0" to all three controls results in expanding their height, as shown in Figure
3.7 (middle).

3
FIGURE 3.7 (left) The three Button controls with their text aligned to the left, center, and
right, (middle) the vertical available space of the container apportioned equally among the three
Button controls, and (right) the text of the three Button controls vertically aligned to the center

In the middle image of Figure 3.7, we see that the text in the Apple and Banana controls is
not at the vertical center, so let’s modify their android:gravity value, as shown here:

android:gravity="center_vertical" for the Apple control

android:gravity="center_vertical|right" for the Banana control

The center_vertical value aligns the content vertically to the center of the control, and
the right value aligns the content to the right of the control. We can combine the values
of the attribute using the | operator. After applying the values as shown in the preceding
two code lines, we get the output shown in Figure 3.7 (right).

RelativeLayout
In RelativeLayout, each child element is laid out in relation to other child elements; that
is, the location of a child element is specified in terms of the desired distance from the
existing children. To understand the concept of relative layout practically, let’s create a
112 CHAPTER 3 Laying Out Controls in Containers

new Android project called RelativeLayoutApp. Modify its layout file activity_relative_
layout_app.xml to appear as shown in Listing 3.6.

LISTING 3.6 The activity_relative_layout_app.xml File on Arranging the Button Controls


in the RelativeLayout Container
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/Apple"
android:text="Apple"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:layout_marginLeft="20dip" />
<Button
android:id="@+id/Mango"
android:text="Mango"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="28dip"
android:layout_toRightOf="@id/Apple"
android:layout_marginLeft="15dip"
android:layout_marginRight="10dip"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/Banana"
android:text="Banana"
android:layout_width="200dip"
android:layout_height="50dip"
android:layout_marginTop="15dip"
android:layout_below="@id/Apple"
android:layout_alignParentLeft="true" />
<Button
android:id="@+id/Grapes"
android:text="Grapes"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="100dp"
android:layout_alignParentRight="true"
android:layout_below="@id/Banana" />
<Button
android:id="@+id/Kiwi"
android:text="Kiwi"
RelativeLayout 113

android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_below="@id/Banana"
android:paddingTop="15dip"
android:paddingLeft="25dip"
android:paddingRight="25dip" />
</RelativeLayout>

Before we understand how the controls in the previous code block are placed, let’s have a
quick look at different attributes used to set the positions of the layout controls.

3
Layout Control Attributes
The attributes used to set the location of the control relative to a container are

▶ android:layout_alignParentTop—The top of the control is set to align with the top


of the container.

▶ android:layout_alignParentBottom—The bottom of the control is set to align with


the bottom of the container.

▶ android:layout_alignParentLeft—The left side of the control is set to align with


the left side of the container.

▶ android:layout_alignParentRight—The right side of the control is set to align with


the right side of the container.

▶ android:layout_centerHorizontal—The control is placed horizontally at the center


of the container.

▶ android:layout_centerVertical—The control is placed vertically at the center of


the container.

▶ android:layout_centerInParent—The control is placed horizontally and vertically


at the center of the container.

The attributes to control the position of a control in relation to other controls are

▶ android:layout_above—The control is placed above the referenced control.

▶ android:layout_below—The control is placed below the referenced control.

▶ android:layout_toLeftOf—The control is placed to the left of the referenced control.

▶ android:layout_toRightOf—The control is placed to the right of the referenced


control.

The attributes that control the alignment of a control in relation to other controls are

▶ android:layout_alignTop— The top of the control is set to align with the top of the
referenced control.
114 CHAPTER 3 Laying Out Controls in Containers

▶ android:layout_alignBottom—The bottom of the control is set to align with the


bottom of the referenced control.

▶ android:layout_alignLeft—The left side of the control is set to align with the left
side of the referenced control.

▶ android:layout_alignRight—The right side of the control is set to align with the


right side of the referenced control.

▶ android:layout_alignBaseline—The baseline of the two controls will be aligned.

For spacing, Android defines two attributes: android:layout_margin and android:padding.


The android:layout_margin attribute defines spacing for the container, while
android:padding defines the spacing for the view. Let’s begin with padding.

▶ android:padding—Defines the spacing of the content on all four sides of the


control. To define padding for each side individually, use android:paddingLeft,
android:paddingRight, android:paddingTop, and android:paddingBottom.

▶ android:paddingTop—Defines the spacing between the content and the top of the
control.

▶ android:paddingBottom—Defines the spacing between the content and the bottom


of the control.

▶ android:paddingLeft—Defines the spacing between the content and the left side of
the control.

▶ android:paddingRight—Defines the spacing between the content and the right side
of the control.

Here are the attributes that define the spacing between the control and the container:

▶ android:layout_margin—Defines the spacing of the control in relation to the


controls or the container on all four sides. To define spacing for each side indi-
vidually, we use the android:layout_marginLeft, android:layout_marginRight,
android:layout_marginTop, and android:layout_marginBottom options.

▶ android:layout_marginTop—Defines the spacing between the top of the control and


the related control or container.

▶ android:layout_marginBottom—Defines the spacing between the bottom of the


control and the related control or container.

▶ android:layout_marginRight—Defines the spacing between the right side of the


control and the related control or container.

▶ android:layout_marginLeft—Defines the spacing between the left side of the


control and the related control or container.
RelativeLayout 115

The layout file activity_relative_layout_app.xml arranges the controls as follows:

The Apple button control is set to appear at a distance of 15dip from the top and
20dip from the left side of the RelativeLayout container. The width of the Mango
button control is set to consume the available horizontal space. The text Mango
appears at a distance of 28dip from all sides of the control. The Mango control is set
to appear to the right of the Apple control. The control is set to appear at a distance
of 15dip from the control on the left and 10dip from the right side of the relative
layout container. Also, the top of the Button control is set to align with the top of the
container.

The Banana button control is assigned the width and height of 200dip and 50dip,

3
respectively. The control is set to appear 15dip below the Apple control. The left side
of the control is set to align with the left side of the container.

The Grapes button control is set to appear below the Banana button control, and
its width is set to expand just enough to accommodate its content. The height of
the control is set to take up all available vertical space. The text Grapes is automati-
cally aligned vertically; that is, it appears at the center of the vertical height when
the height attribute is set to match_parent. The minimum width of the control is
set to 100dip. The right side of the control is set to align with the right side of the
container.

The Kiwi Button control is set to appear below the Banana control. Its width is set to
100dip, and the height is set to just accommodate its content. The text Kiwi is set to
appear at the distance of 15dip, 25dip, and 25dip from the top, left, and right bound-
ary of the control.

We don’t need to make any changes to the RelativeLayoutAppActivity.java file. Its


original content is as shown in Listing 3.7.

LISTING 3.7 The Default Code in the Activity File RelativeLayoutAppActivity.java


package com.androidunleashed.relativelayoutapp;

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

public class RelativeLayoutDemoActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_relative_layout_app);
}
}

When the application is run, we see the output shown in Figure 3.8.
116 CHAPTER 3 Laying Out Controls in Containers

FIGURE 3.8 The five Button controls’ layout relative to each other

We can make the text Grapes appear centrally at the top row by adding the following line:
android:gravity="center_horizontal"

So, its tag appears as follows:

<Button
android:id="@+id/Grapes"
android:text="Grapes"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="100dp"
android:layout_alignParentRight="true"
android:layout_below="@id/Banana"
android:gravity="center_horizontal" />

The output is modified to appear as shown in Figure 3.9.


RelativeLayout 117

3
FIGURE 3.9 The Grapes Button control aligned horizontally at the center

Let’s explore the concept of laying out controls in the RelativeLayout container by writing
an application. The application that we are going to create is a simple Login Form appli-
cation that asks the user to enter a User ID and Password. The TextView, EditText, and
Button controls in the application are laid out in a RelativeLayout container (see Figure
3.10—left). If either the User ID or Password is left blank, the message The User ID or
password is left blank. Please Try Again is displayed. If the correct User ID and
Password, in this case, guest, are entered, then a welcome message is displayed. Otherwise,
the message The User ID or password is incorrect. Please Try Again is displayed.

So, let’s create the application. Launch the Eclipse IDE and create a new Android appli-
cation called LoginForm. Arrange four TextView controls, two EditText controls, and a
Button control in RelativeLayout, as shown in the layout file activity_login_form.xml
displayed in Listing 3.8.

LISTING 3.8 The activity_login_form.xml on Laying Out the TextView, EditText, and
Button Controls in the RelativeLayout Container

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/sign_msg"
118 CHAPTER 3 Laying Out Controls in Containers

android:text = "Sign In"


android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:typeface="serif"
android:textSize="25dip"
android:textStyle="bold"
android:padding="10dip"
android:layout_centerHorizontal="true"/>
<TextView
android:id="@+id/user_msg"
android:text = "User ID:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:layout_below="@+id/sign_msg" />
<EditText
android:id="@+id/user_ID"
android:layout_height="wrap_content"
android:layout_width="250dip"
android:layout_below="@+id/sign_msg"
android:layout_toRightOf="@+id/user_msg"
android:singleLine="true" />
<TextView
android:id="@+id/password_msg"
android:text = "Password:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/user_msg"
android:layout_margin="10dip"
android:paddingTop="10dip"/>
<EditText
android:id="@+id/password"
android:layout_height="wrap_content"
android:layout_width="250dp"
android:singleLine="true"
android:layout_below="@+id/user_ID"
android:layout_toRightOf="@+id/password_msg"
android:password="true" />
<Button
android:id="@+id/login_button"
android:text="Sign In"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dip"
android:layout_below="@+id/password_msg"/>
RelativeLayout 119

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/response"
android:layout_below="@+id/login_button"/>
</RelativeLayout>

The controls in the application are arranged in the RelativeLayout, as explained here:

▶ Through the TextView control sign_msg, the text Sign In is displayed horizontally
centered at the top. It is displayed in bold serif font, 25 dip in size. The text is

3
padded with a space of 10dip on all four sides of its container.

▶ Another TextView control, user_msg, displays the text User ID below the TextView
sign_msg. The TextView is placed 10dip from all four sides.

▶ An EditText control user_ID is displayed below sign_msg and to the right of user_
msg. The width assigned to the TextView control is 250 dip and is set to single-line
mode, so if the user types beyond the given width, the text scrolls to accommodate
extra text but does not run over to the second line.

▶ A TextView password_msg control displaying the text Password: is displayed below


the TextView user_msg. The TextView control is placed at a spacing of 10dip from
all four sides, and the text Password: is displayed at 10dip from the control’s top
boundary.

▶ An EditText control password is displayed below the EditText user_ID and to the
right of the TextView password_msg. The width assigned to the TextView control
is 250 dip and is set to single-line mode. In addition, the typed characters are
converted into dots for security.

▶ A Button control login_button with the caption Sign In is displayed below the
TextView password_msg. The button is horizontally centered and is set to appear at
10dip distance from the EditText control password.

▶ A TextView control response is placed below the Button login_button. It is used to


display messages to the user when the Sign In button is pressed after entering User
ID and Password.

To authenticate the user, we need to access the User ID and Password that is entered
and match these values against the valid User ID and Password. In addition, we want to
validate the EditText controls to confirm that none of them is blank. We also want to
welcome the user if he or she is authorized. To do all this, we write the code in the activ-
ity file LoginFormActivity.java as shown in Listing 3.9.
120 CHAPTER 3 Laying Out Controls in Containers

LISTING 3.9 Code Written in the Java Activity File LoginFormActivity.java


package com.androidunleashed.loginform;

import android.app.Activity;
import android.os.Bundle;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.view.View;
import android.widget.TextView;

public class LoginFormActivity extends Activity implements OnClickListener {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_form);
Button b = (Button)this.findViewById(R.id.login_button);
b.setOnClickListener(this);
}

public void onClick(View v) {


EditText userid = (EditText) findViewById(R.id.user_ID);
EditText password = (EditText) findViewById(R.id.password);
TextView resp = (TextView)this.findViewById(R.id.response);
String usr = userid.getText().toString();
String pswd = password.getText().toString();
if(usr.trim().length() == 0 || pswd.trim().length() == 0){
String str = "The User ID or password is left blank \nPlease Try Again";
resp.setText(str);
}
else{
if(usr.equals("guest") && pswd.equals("guest")) resp.setText("Welcome " +
usr+ " ! ");
else resp.setText("The User ID or password is incorrect \nPlease Try Again");
}
}
}

The Button control is accessed from the layout file and is mapped to the Button object b.
This activity implements the OnClickListener interface. Hence, the class implements the
callback method onClick(), which is invoked when a click event occurs on the Button
control.

In the onClick() method, the user_ID and password EditText controls are accessed
from the layout file and mapped to the EditText objects userid and password. Also, the
TextView control response is accessed from the layout file and is mapped to the TextView
AbsoluteLayout 121

object resp. The User ID and password entered by the user in the two EditText controls
are accessed through the objects userid and password and assigned to the two Strings usr
and pswd, respectively. The data in the usr and pswd strings is checked for authentica-
tion. If the user has left any of the EditText controls blank, the message The User ID or
password is left blank. Please Try Again is displayed, as shown in Figure 3.10 (left).
If the User ID and password are correct, then a welcome message is displayed (see Figure
3.10—right). Otherwise, the message The User ID or password is incorrect. Please
Try Again is displayed, as shown in Figure 3.10 (middle).

3
FIGURE 3.10 (left) The Login Form displays an error if fields are left blank, (middle) the
Password Incorrect message displays if the user ID or password is incorrect, and (right) the
Welcome message displays when the correct user ID and password are entered.

AbsoluteLayout
Each child in an AbsoluteLayout is given a specific location within the bounds of the
container. Such fixed locations make AbsoluteLayout incompatible with devices of differ-
ent screen size and resolution. The controls in AbsoluteLayout are laid out by specifying
their exact X and Y positions. The coordinate 0,0 is the origin and is located at the top-left
corner of the screen.

Let’s write an application to see how controls are positioned in AbsoluteLayout. Create a
new Android Project called AbsoluteLayoutApp. Modify its layout file, activity_
absolute_layout_app.xml, as shown in Listing 3.10.

LISTING 3.10 The Layout File activity_absolute_layout_app.xml on Arranging Controls in


the AbsoluteLayout Container
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Product Form"
android:textSize="20sp"
122 CHAPTER 3 Laying Out Controls in Containers

android.textStyle="bold"
android:layout_x="90dip"
android:layout_y="2dip"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Code:"
android:layout_x="5dip"
android:layout_y="40dip" />
<EditText
android:id="@+id/product_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="100dip"
android:layout_x="110dip"
android:layout_y="30dip" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Name:"
android:layout_x="5dip"
android:layout_y="90dip"/>
<EditText
android:id="@+id/product_name"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:minWidth="200dip"
android:layout_x="110dip"
android:layout_y="80dip"
android:scrollHorizontally="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Price:"
android:layout_x="5dip"
android:layout_y="140dip" />
<EditText
android:id="@+id/product_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="100dip"
android:layout_x="110dip"
android:layout_y="130dip" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
AbsoluteLayout 123

android:id="@+id/click_btn"
android:text="Add New Product"
android:layout_x="80dip"
android:layout_y="190dip" />
</AbsoluteLayout>

The controls in activity_absolute_layout_app.xml are as follows:

▶ The New Product Form TextView is set to appear 90dip from the left and 2dip from
the top side of the container. The size of the text is set to 20sp, and its style is set to
bold.

3
▶ The Product Code TextView is set to appear 5dip from the left and 40dip from the
top side of the container.

▶ The product_code EditText control is set to appear 110dip from the left and 30dip
from the top side of the container. The minimum width of the control is set
to 100dp.

▶ The ProductName TextView control is set to appear 5dip from the left and 90dip
from the top side of the container.

▶ The product_name EditText control is set to appear 110dip from the left and 80dip
from the top side of the container. The minimum width of the control is set to
200dip, and its text is set to scroll horizontally when the user types beyond its
width.

▶ The Product Price TextView is set to appear 5dip from the left and 140dip from the
top side of the container.

▶ The product_price EditText control is set to appear 110dip from the left and
130dip from the top side of the container. The minimum width of the control is set
to 100dip.

▶ The click_btn Button, Add New Product, is set to appear 80dip from the left and
190dip from the top side of the container.

If we don’t specify the x, y coordinates of a control in AbsoluteLayout, it is placed in the


origin point, that is, at location 0,0. If the value of the x and y coordinates is too large,
the control does not appear on the screen. The values of the x and y coordinates are speci-
fied in any units, such as sp, in, mm, and pt.

After specifying the locations of controls in the layout file activity_absolute_layout_


app.xml, we can run the application. There is no need to make any changes in the file
AbsoluteLayoutAppActivity.java. When the application is run, we get the output shown
in Figure 3.11.
124 CHAPTER 3 Laying Out Controls in Containers

FIGURE 3.11 Different controls laid out in AbsoluteLayout

The AbsoluteLayout class is not used often, as it is not compatible with Android phones of
different screen sizes and resolutions.

The next layout we are going to discuss is FrameLayout. Because we will learn to display
images in FrameLayout, let’s first take a look at the ImageView control that is often used to
display images in Android applications.

Using ImageView
An ImageView control is used to display images in Android applications. An image can be
displayed by assigning it to the ImageView control and including the android:src attri-
bute in the XML definition of the control. Images can also be dynamically assigned to the
ImageView control through Java code.

A sample ImageView tag when used in the layout file is shown here:

<ImageView
android:id="@+id/first_image"
android:src = "@drawable/bintupic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:maxHeight="100dip"
android:maxWidth="250dip"
android:minHeight="100dip"
android:minWidth="250dip"
android:resizeMode="horizontal|vertical" />
FrameLayout 125

Almost all attributes that we see in this XML definition should be familiar, with the excep-
tion of the following ones:

▶ android:src—Used to assign the image from drawable resources. We discuss draw-


able resources in detail in Chapter 4. For now, assume that the image in the res/
drawable folder is set to display through the ImageView control via this attribute.

Example:

android:src = "@drawable/bintupic"

You do not need to specify the image file extension. JPG and GIF files are supported,
but the preferred image format is PNG.

3
▶ android:scaleType—Used to scale an image to fit its container. The valid values for
this attribute include fitXY, center, centerInside, and fitCenter. The value fitXY
independently scales the image around the X and Y axes without maintaining the
aspect ratio to match the size of container. The value center centers the image in
the container without scaling it. The value centerInside scales the image uniformly,
maintaining the aspect ratio so that the width and height of the image fit the size
of its container. The value fitCenter scales the image while maintaining the aspect
ratio, so that one of its X or Y axes fits the container.

▶ android:adjustViewBounds—If set to true, the attribute adjusts the bounds of the


ImageView control to maintain the aspect ratio of the image displayed through it.

▶ android:resizeMode—The resizeMode attribute is used to make a control resizable


so we can resize it horizontally, vertically, or around both axes. We need to click and
hold the control to display its resize handles. The resize handles can be dragged in
the desired direction to resize the control. The available values for the resizeMode
attribute include horizontal, vertical, and none. The horizontal value resizes the
control around the horizontal axis, the vertical value resizes around the vertical
axis, the both value resizes around both the horizontal and vertical axes, and the
value none prevents resizing.

FrameLayout
FrameLayout is used to display a single View. The View added to a FrameLayout is placed
at the top-left edge of the layout. Any other View added to the FrameLayout overlaps the
previous View; that is, each View stacks on top of the previous one. Let’s create an applica-
tion to see how controls can be laid out using FrameLayout.

In the application we are going to create, we will place two ImageView controls in the
FrameLayout container. As expected, only one ImageView will be visible, as one ImageView
will overlap the other ImageView, assuming both ImageView controls are of the same size.
We will also display a button on the ImageView, which, when selected, displays the hidden
ImageView underneath.
126 CHAPTER 3 Laying Out Controls in Containers

Let’s start with the application. Create a new Android project called FrameLayoutApp.
To display images in Android applications, the image is first copied into the res/drawable
folder and from there, it is referred to in the layout and other XML files. We look at the
procedure for displaying images, as well as the concept of drawable resources, in detail
in Chapter 4. For the time being, it is enough to know that to enable the image(s) to be
referred to in the layout files placed in the res/drawable folder, the image needs to exist
in the res/drawable folder. There are four types of drawable folders: drawable-xhdpi,
drawable-hdpi, /res/drawable-mdpi, and /res/drawable-ldpi. We have to place images
of different resolutions and sizes in these folders. The graphics with the resolutions 320
dpi, 240dpi, 160 dpi, and 120dpi (96 x 96 px, 72 x 72 px, 48 x 48 px, and 36 x 36 px),
are stored in the res/drawable-xhdpi, res/drawable-hdpi, res/drawable-mdpi, and res/
drawable-ldpi folders, respectively. The application picks up the appropriate graphic from
the correct folder. So, if we copy two images called bintupic.png and bintupic2.png of
the preceding size and resolution and paste them into the four res/drawable folders, the
Package Explorer resembles Figure 3.12.

FIGURE 3.12 The Package Explorer window showing the two images, bintupic.png and
bintupic2.png, dropped into the res/drawable folders

To display two ImageViews and a TextView in the application, let’s write the code in the
layout file activity_frame_layout_app.xml as shown in Listing 3.11.
FrameLayout 127

LISTING 3.11 The Layout File activity_frame_layout_app.xml on Arranging the ImageView


and TextView Controls in the FrameLayout Container
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/first_image"
android:src = "@drawable/bintupic"
android:layout_width="match_parent"

3
android:layout_height="match_parent"
android:scaleType="fitXY" />
<ImageView
android:id="@+id/second_image"
android:src = "@drawable/bintupic2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click the image to switch"
android:layout_gravity="center_horizontal|bottom"
android:padding="5dip"
android:textColor="#ffffff"
android:textStyle="bold"
android:background="#333333"
android:layout_marginBottom="10dip" />
</FrameLayout>

The first_image and second_image ImageView controls are set to display the images
bintupic.png and bintupic2.png, respectively. To make the two images stretch to cover
the entire screen, the scaleType attribute in the ImageView tag is set to fitXY. A TextView,
Click the image to switch, is set to display at the horizontally centered position and
at a distance of 10dip from the bottom of the container. The spacing between the text
and the boundary of the TextView control is set to 5dip. The background of the text is set
to a dark color, the foreground color is set to white, and its style is set to bold. When a
user selects the current image on the screen, the image should switch to show the hidden
image. For this to occur, we need to write code in the activity file as shown in Listing 3.12.
128 CHAPTER 3 Laying Out Controls in Containers

LISTING 3.12 Code Written in the Java Activity File FrameLayoutAppActivity.java


package com.androidunleashed.framelayoutapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
import android.view.View.OnClickListener;
import android.view.View;

public class FrameLayoutAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frame_layout_app);
final ImageView first_image = (ImageView)this.findViewById(R.id.first_image);
final ImageView second_image = (ImageView)this.findViewById(R.id.second_image);
first_image.setOnClickListener(new OnClickListener(){
public void onClick(View view) {
second_image.setVisibility(View.VISIBLE);
view.setVisibility(View.GONE);
}
});
second_image.setOnClickListener(new OnClickListener(){
public void onClick(View view) {
first_image.setVisibility(View.VISIBLE);
view.setVisibility(View.GONE);
}
});
}
}

The two first_image and second_image ImageView controls are located through the
findViewById method of the Activity class and assigned to the two ImageView objects,
first_image and second_image, respectively. We register the click event by calling the
setOnClickListener() method with an OnClickListener. An anonymous listener is
created on the fly to handle click events for the ImageView. When the ImageView is
clicked, the onClick() method of the listener is called. In the onClick() method, we
switch the images; that is, we make the current ImageView invisible and the hidden
ImageView visible. When the application runs, we see the output shown in Figure 3.13
(left). The application shows an image, and the other image is hidden behind it because in
FrameLayout one View overlaps the other. When the user clicks the image, the images are
switched, as shown in Figure 3.13 (right).
TableLayout 129

3
FIGURE 3.13 (left) An image and a TextView laid out in FrameLayout, and (right) the images
switch when clicked

TableLayout
The TableLayout is used for arranging the enclosed controls into rows and columns.
Each new row in the TableLayout is defined through a TableRow object. A row can have
zero or more controls, where each control is called a cell. The number of columns in a
TableLayout is determined by the maximum number of cells in any row. The width of a
column is equal to the widest cell in that column. All elements are aligned in a column;
that is, the width of all the controls increases if the width of any control in the column is
increased.

NOTE
We can nest another TableLayout within a table cell, as well.

Operations Applicable to TableLayout


We can perform several operations on TableLayout columns, including stretching, shrink-
ing, collapsing, and spanning columns.

Stretching Columns
The default width of a column is set equal to the width of the widest column, but we can
stretch the column(s) to take up available free space using the android:stretchColumns
130 CHAPTER 3 Laying Out Controls in Containers

attribute in the TableLayout. The value assigned to this attribute can be a single column
number or a comma-delimited list of column numbers. The specified columns are
stretched to take up any available space on the row.

Examples:

▶ android:stretchColumns="1"—The second column (because the column numbers


are zero-based) is stretched to take up any available space in the row.

▶ android:stretchColumns="0,1"—Both the first and second columns are stretched to


take up the available space in the row.

▶ android:stretchColumns="*"—All columns are stretched to take up the available


space.

Shrinking Columns
We can shrink or reduce the width of the column(s) using the android:shrinkColumns
attribute in the TableLayout. We can specify either a single column or a comma-delimited
list of column numbers for this attribute. The content in the specified columns word-
wraps to reduce their width.

NOTE
By default, the controls are not word-wrapped.

Examples:

▶ android:shrinkColumns="0"—The first column’s width shrinks or reduces by word-


wrapping its content.

▶ android:shrinkColumns="*"—The content of all columns is word-wrapped to shrink


their widths.

Collapsing Columns
We can make the column(s) collapse or become invisible through the android:
collapseColumns attribute in the TableLayout. We can specify one or more comma-delim-
ited columns for this attribute. These columns are part of the table information but are
invisible. We can also make column(s) visible and invisible through coding by passing the
Boolean values false and true, respectively, to the setColumnCollapsed() method in the
TableLayout. For example:

▶ android:collapseColumns="0"—The first column appears collapsed; that is, it is


part of the table but is invisible. It can be made visible through coding by using the
setColumnCollapsed() method.
Unit 3 – II - Utilizing Resources and Media

Resources include text data, bitmaps, audio, videos, and other items used by the
Android application. Most commonly resources are kept separately in XML files and
accessed in Java code through the IDs assigned to them. In this chapter you learn to access
media too, that is, access and use images, audio, and video in Android applications.

RESOURCES
Resources in Android refer to the external files that hold the information, such as
strings, images, layouts, and audio, to be supplied to an Android application. Because
resources are external, we can maintain and modify them whenever we want without
disturbing the code. For example, the strings resource keeps the strings used in an Android
application. Changing the string content in the resource file is easier when compared to
applying changes to hard-coded strings that are scattered in the application code. Also, by
creating several resource files, each supporting different hardware, we can make our
applications applicable to diverse hardware systems. For example, we can have several
layouts for screen size and orientation and use them dynamically when we want.
Resources are broadly divided into three categories—values, drawable, and layout—
and are stored in the res folder of our project hierarchy. The values resources in turn represent
resources such as strings, colors, dimensions, styles, and string or integer arrays. All resource
types have a respective subfolder in the res folder. The ADT Wizard automatically creates
a res folder that contains subfolders for the values, drawable, and layout resources, as shown
in Figure 4.1.

Figure 4.1. The res folder showing the nested drawable (drawable-hdpi, drawable-ldpi,drawable-mdpi) layouts
and values folders and their content

Types of Resources
A brief outline of the three folders is provided here:
• drawable folder—Depending on the target platform chosen, our application can have either
a single directory, drawable, or four directories, drawable-ldpi, drawable-mdpi, drawable-hdpi,
anddrawable-xhdpi, where we can store the images used in our application. If our application
has a single directory, drawable, then the images to be used in our application, regardless of
resolution, are stored in it. If our application has four directories, then the images with
different screen resolutions are stored in the respective directories. That is, the images of low,
medium, high, and extra high resolutions are stored in the drawable-ldpi, drawable-mdpi, drawable-
hdpi, and drawable-xhdpi directories, respectively. Android chooses the image(s) from the
respective directory, depending on the density of the device used to run the application.
• layout folder—This folder contains a layout file automatically created for us. The default
name assigned to this file is activity_main.xml, but we can assign any name to it. In Chapter 3,
“Laying Out Controls in Containers,” we saw how to use this file to lay out Views in the
desired format.
• menu folder—This folder contains XML file(s) that represent application menus. Again, the
default name assigned to the menu file that is automatically created for us is activity_main.xml,
but we can change the name if we want.
• values folder—This folder by default contains a strings.xml file that we can use to define
values resources that include strings, colors, dimensions, styles, and string or integer arrays.
We can also create individual XML files for each of these resources instead. The folder also
contains thestyles.xml file that declares the standard platform’s default light theme. The
following is a list of some XML files that we can create in the values folder:
• arrays.xml—For defining arrays resources
• colors.xml—For defining color resources that define color values
• dimens.xml—For defining dimension resources to standardize certain application
measurements
• strings.xml—For defining string resources
• styles.xml—For defining styles resources to format or change the appearance of our views
and application
There are many Android devices with different Android versions, and managing themes
across them is a critical task. To manage themes for different Android versions,
different values folders in the /resfolder containing individual themes are maintained. The idea
is that on the basis of the platform version, the desired theme will be automatically selected
from the respective folder.
• values-v11—The folder contains the styles.xml file that declares the holographic theme,
which is used when the application runs on Android 3.0 (API Level 11) or higher. That is, if
the API level of the device is 11 or higher, the styles.xml file present in this folder overrides
the styles.xml file present in the res/values folder.
• values-v14—The folder contains the styles.xml file that declares the DeviceDefault theme,
which is used when the application runs on Android 4.0 (API Level 14) or higher.
Besides these default subdirectories automatically created by ADT, there are several
subdirectories that we can manually create in the res folder to categorize and keep our
resources tidy. Table 4.1 shows the list of supported subdirectories in the res folder.
Table 4.1. Supported Subdirectories of the res Folder

When our application is built, all resources are compiled and included in our
application package. On compilation, an R class file is created that contains references to all
the resources created and hence enables us to reference them in the Java code. For each of the
resource types, the R class contains static subclasses for string, drawable, and layout resource
types. The subclasses created areR.string, R.drawable, and R.layout, respectively. Through these
subclasses, we can access their associated resources in Java code.
Note
Don’t edit the R.java file, as it is regenerated every time something gets changed, added, or deleted in
the /res/* subdirectory.

CREATING VALUES RESOURCES


The resources in the values directory include different types, such
as strings, colors,dimensions, and string or integer arrays. All the values are stored in XML files in
theres/values folder. It is preferred to have a separate XML file for each type of resource in
the valuesdirectory. The filename can be anything, but most commonly, the string resources
file is namedstrings.xml. Remember, the resource filenames should contain only lowercase
letters, numbers, period (.), and underscore (_) symbols.
Note
We can have any number of XML files to represent resources, provided they reside in
the/res/values subdirectory. Never save resource files directly inside the res/ folder—it will cause a
compiler error.
To create Values resources, let’s create an Android project called ValuesResourcesApp.
Thestrings.xml file that is automatically created for us by the ADT Wizard contains the default
content shown in Listing 4.1.

Listing 4.1. Default Code in the strings.xml File

<resources>
<string name="app_name">ValuesResourcesApp</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string
name="title_activity_values_resources_app">ValuesResourcesAppActivity</string>
</resources>
The two string resources with the name attributes hello and app_name are assigned to
theTextView (in main.xml) and label attribute of the Activity tag (in AndroidManifest.xml) to display
the name of the activity and the application name, respectively, while running the project.
Let’s modify the strings.xml file to appear as shown in Listing 4.2.

Listing 4.2. Code Written in the strings.xml File

<resources>
<string name="app_name">ValuesResourcesApp</string>
<string name="menu_settings">Settings</string>
<string
name="title_activity_values_resources_app">ValuesResourcesAppActivity</string>
<string name="str_name">XYZ Restaurant</string>
<string name="str_address">11, Hill View Street, New York</string>
<string name="str_message"><b>Welcome</b></string>
</resources>
We can see that the string resources file has a root element, <resources>, followed by
one or more child elements, <string>. Each <string> element represents one string resource.
Besides the text for the string resource, it contains a name property used to assign a unique
resource ID to the string. That is, the names assigned to the four string
resources, app_name, str_name, str_address, andstr_message, are the resource IDs of the respective
strings, and we can use these resource IDs in other resource files or the Java code for
accessing the respective string resources.
We can use the string resources of the preceding XML file in other resource files by
using the following syntax:

@string/resource_ID

For example, to access the string resource with the resource ID str_address in another
resource file, we use the following code:

@string/str_address

All the string resources mentioned in the preceding string resource file will be
compiled and placed in the R.java file. In the Java code, we can access the resources from
the R.java file, using the following syntax:

R.string.resource_ID

In preceding syntax, the string refers to the resource type; that is, every resource ID
needs to be prefixed by the resource type. Likewise, to access
the drawable and layout resources, we prefix the resource ID by R.drawable and R.layout,
respectively. There is no need to add any prefix while accessing any control from the layout.
The resource ID is enough. The syntax is

R.id.resource_ID
Hence, to access the string resource with the resource ID str_address in the Java code,
we use the following statement:

R.string.str_name

We use the getString() method and pass the resource ID of the concerned string
resource to access it in Java code. Hence, the complete command to access the string resource
with the resource IDstr_address is

getString(R.string.str_address);

In the strings.xml file shown in Listing 4.2, we can also use HTML tags <b>, <i>,
and <u> to make a string appear bold, italicized, or underlined. To access the string resources
defined in the filestrings.xml and to apply them to the TextView controls, the layout
fileactivity_values_resources_app.xml may be modified to appear as shown in Listing 4.3.

Listing 4.3. Code Written in the Layout File activity_values_resources_app.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/name_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_name" />
<TextView
android:id="@+id/address_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/message_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_message" />
</LinearLayout>
In this code block, the statement android:text="@string/str_name" accesses a string
resource from a resource file res/values/strings.xml, whose name property is str_name. The text in
the string resource str_name is assigned to the TextView for display. Similarly, the string
resourcestr_message is accessed and assigned to the TextView message_view. Hence, the text XYZ
Restaurant and the Welcome message appear on the screen through the first and
third TextViewcontrols, name_view and message_view, respectively. But the
middle TextView, address_view, does not display any text, as it is not assigned any string
resource. Why?
The answer is that we will learn to assign a string resource to this TextView through
Java code. The code written in the Java file ValuesResourcesAppActivity.java may appear as
shown in Listing 4.4.
Listing 4.4. Code Written in the Java Activity File ValuesResourcesAppActivity.java

package com.androidunleashed.valuesresourcesapp;

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

public class ValuesResourcesAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_values_resources_app);
String strAddress=getString(R.string.str_address);
TextView addressView=(TextView)findViewById(R.id.address_view);
addressView.setText(strAddress);
}
}
The string resource with the resource ID str_address is accessed and assigned to the
String objectstrAddress. The TextView with the ID addressView is accessed from the layout and is
mapped to the TextView object addressView. The content of the string resource that is saved in
thestrAddress object is assigned to the TextView to display. That is, the content of the string
resourcestr_address is assigned to a TextView so it will be displayed on the screen. We get the
output shown in Figure 4.2.

Figure 4.2. The three TextViews displaying the text assigned to them via String resource and Java code

Let’s change the size of the text in these TextView controls via dimension resources.

Dimension Resources
Dimension resources are used for standardizing certain application measurements.
These resources can be used to specify the sizes for fonts, layouts, and widgets. Also, we can
modify the size of any control in the application without changing the code. Besides this, we
can define dimensions for different screen resolutions and densities to support different
hardware.
To try out dimension resources, let’s open the application ValuesResourcesApp and add
an XML file called dimens.xml to the values folder. To the dimens.xml file, add the code as
shown in Listing 4.5.
Listing 4.5. Code Written in the dimens.xml File

<?xml version="1.0" encoding="utf-8"?>


<resources>
<dimen name="small_size">15dp</dimen>
<dimen name="medium_size">15sp</dimen>
<dimen name="large_size">20pt</dimen>
</resources>
We can see that the dimension resource is defined through the dimen element.
The dimen element contains a numerical value followed by unit of measurement. Like other
resources, it includes the nameproperty to specify the ID of the resource.
We can use any of the following units of measurement:
• px—Pixels
• in—Inches
• mm—Millimeters
• pt—Points
• dp—Density-independent pixels based on a 160-dpi (pixel density per inch) screen
• sp—Scale-independent pixels
In the strings.xml file, we have defined three dimension resources: 15dp, 15sp, and 20pt,
represented by the three resource IDs small_size, medium_size, and large_size, respectively. Let’s
apply the dimension resources to our TextView controls name_view, address_view,
andmessage_view. First, we learn to apply dimension resources through the layout file followed
by Java code. To apply dimension resources to the TextView controls,
modifyactivity_values_resources_app.xml to appear as shown in Listing 4.6.

Listing 4.6. The Layout File activity_values_resources_app.xml on Applying Dimension Resources


to TextView Controls

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/name_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_name"
android:textSize="@dimen/small_size" />
<TextView
android:id="@+id/address_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/message_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_message"
android:textSize="@dimen/large_size" />
</LinearLayout>
In the preceding code block, the two statements

android:textSize="@dimen/small_size"

and

android:textSize="@dimen/large_size"

access the two dimension resources small_size and large_size and apply to the two TextViewswith
the IDs name_view and message_view, respectively. Their text size is set to 15px and 20sp,
respectively. Now let’s see how to apply dimension resources to a View via Java code.
To apply the dimension resource medium_size to our TextView address_view, add these statements
to the Java file ValuesResourcesAppActivity.java:

float addressSize= this.getResources().getDimension(R.dimen.medium_size);


addressView.setTextSize(addressSize);

The TextView to which we want to apply the dimension resource is accessed from the
layout file and mapped to the TextView object addressView. Thereafter, we access our Resources
object by calling the getResources() method on our activity object. Then, through the Resources
object, we access the dimension by supplying its resource ID to the getDimension() method.
The dimension accessed is then applied to the TextView using the setTextSize() method. After
the application is run, we find that the three TextView controls appear in the sizes defined in
the dimension resources, as shown in Figure 4.3.

Figure 4.3. Different dimensions applied to the three TextViews via dimension resources

Let’s now see how to apply colors to our Views via color resources.

Color Resources
To define a color resource, we use the color element. The color value is specified in the
form ofhexadecimal RGB values preceded by an optional Alpha channel. The Alpha channel
represents the transparency. We can specify the color either through single-character hex
values or double-character hex values formats, as shown here:
• #RGB—For example, #F00 for a Red color.
• #RRGGBB—For example, #FF0000 for a Red color
• #ARGB—For example, #5F00 for a Red color with an Alpha of 5.
• #AARRGGBB—For example, #50FF0000 for a Red color with an Alpha of 50.
To apply color resources to our application ValuesResourcesApp, let’s add an XML file
calledcolors.xml to the values folder. In the colors.xml file, define a few color resources by
writing the following lines of code in it:

<?xml version="1.0" encoding="utf-8"?>


<resources>
<color name="red_color">#F00</color>
<color name="green_color">#00FF00</color>
<color name="blue_alpha_color">#500000FF</color>
</resources>

This code block defines three color resources that represent the three colors red, green,
and blue (bit transparent) through the resource IDs red_color, green_color, and blue_alpha_color,
respectively. Again, we learn to apply color resources to our Views with two methods: via the
layout file and Java code. To apply color resources via the layout
fileactivity_values_resources_app.xml, let’s modify it to appear as shown in Listing 4.7.

Listing 4.7. The Layout File activity_values_resources_app.xml on Applying Color Resources

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/name_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_name"
android:textSize="@dimen/small_size"
android:textColor="@color/red_color"/>
<TextView
android:id="@+id/address_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/message_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_message"
android:textSize="@dimen/large_size"
android:textColor="@color/blue_alpha_color"/>
</LinearLayout>
In the preceding code block, the two statements

android:textColor="@color/red_color"

and
android:textColor="@color/blue_alpha_color"

access the color resources with the IDs red_color and blueAlpha_color, from the resource file and
assign them to the text of the two TextViews, name_view and message_view. This changes their
color to red and blue, respectively.
To apply the color resource to the TextView address_view, we use Java code. Add the following
lines of code to the Java file ValuesResourcesAppActivity.java to access the color resource and
apply it to the desired View:

int addressColor=this.getResources().getColor(R.color.green_color);
addressView.setTextColor(addressColor);

Here, the Resources object is accessed by calling the getResources() method. The
Resources object, the getColor() method, is called to access the color resource by supplying its
resource ID. The color accessed is then applied to the addressView TextView by using
the setTextColor() method. The complete code in ValuesResourcesAppActivity.java is shown
in Listing 4.8.

Listing 4.8. The Code Written in the Java Activity File ValuesResourcesAppActivity.java

package com.androidunleashed.valuesresourcesapp;

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

public class ValuesResourcesAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_values_resources_app);
String strAddress=getString(R.string.str_address);
TextView addressView=(TextView)findViewById(R.id.address_view);
addressView.setText(strAddress);
float addressSize= this.getResources().getDimension(R.dimen.medium_size);
addressView.setTextSize(addressSize);
int addressColor=this.getResources().getColor(R.color.green_color);
addressView.setTextColor(addressColor);
}
}
When the application is run, we see the three TextView controls appearing in the colors
defined in thecolor resources, as shown in Figure 4.4. Because the print book is in black and
white, the TextViewcontrols are distinguished through different sizes.
Figure 4.4. The three TextViews displayed in different colors applied via the Color Resource.
The TextView controls are distinguished through different sizes.

Styles and Themes


A style is a collection of attributes such as color, font, margin, and padding that we
can apply collectively to our Views, Activity, or an entire application. That is, instead of
applying attributes individually to the components of our application, we can create a style
incorporating all these attributes and quickly apply it instead. Through styles, we can apply a
consistent dynamic look to ourViews, Activity, and to the overall application. Also, we can
easily change the appearance of our Views and application by simply specifying a different
style or modifying the properties of the existing style, all without disturbing the Java code.
A style is created by using a style element with one or more item child elements.
The style element includes a name property to specify the resource ID. Each item element
includes a name property to define the attributes such as color, font, and so on.
An item element defines an attribute and its value shown in this syntax:

<resources>
<style name="resource_ID">
<item name="attribute_name">value </item>
</style>
</resources>

Styles support inheritance; that is, the attributes of any existing style can be accessed
and included in the current style by using the parent property of the style element. For example,
the attributes defined in a style named style1 can be included in the style named style2 by
making use of theparent property in style2 as shown here:

<style name="style2" parent="style1" >

To apply styles to the individual Views in the layout file, open the styles.xml file that
already exists in the values folder. In the styles.xml file, define the styles as shown in Listing
4.9.

Listing 4.9. The Code Written in the styles.xml File

<resources>
<style name="AppTheme" parent="android:Theme.Light" />
<style name="style1">
<item name="android:textColor">#00FF00 </item>
<item name="android:typeface">serif</item>
<item name="android:textSize">30sp </item>
</style>
<style name="style2" parent="style1" >
<item name="android:textColor">#0000FF</item>
<item name="android:typeface">sans</item>
<item name="android:background">#FF0000</item>
<item name="android:padding">10dip</item>
</style>
<style name="style3" parent="style2" >
<item name="android:textColor">#00FF00</item>
<item name="android:background">#00000000</item>
<item name="android:typeface">monospace</item>
<item name="android:gravity">center</item>
</style>
</resources>
We can see that three styles are defined with IDs: style1, style2, and style3, respectively.
Thestyle1 defines three attributes that
• Set the text color to green
• Set the font (typeface) to serif
• Set the font size to 30sp
The style2 inherits style1; hence it automatically gets the preceding three attributes.
The style2overrides the font and text color, changing them to sans and blue, respectively.
Also, style2includes the attributes to set the background color of the text to red and the text
spacing to 10dipfrom all four sides of the container. Thus, it also means that style 2 now has the
attributes that
• Set the font size to 30sp (inherited from style1)
• Set the text color to blue
• Set the font (typeface) to sans
• Set the text background color to red
• Set the padding (text spacing from all four sides of the container) to 10dip
The style3 inherits style2, which means it receives all these attributes. It overrides certain
attributes redefining the text color, background color, and the font to green, black,
and monospace, respectively. Also, style3 includes the gravity attribute set to center that makes the
content of aView appear at the center. Hence, the style3 has the following attributes that
• Set the font size to 30sp
• Set the text color to green
• Set the background color of the text to black
• Set the font (typeface) to monospace
• Set the padding (text spacing from all four sides of the container) to 10dip
• Make the content appear at the center of the View
Let’s apply the three styles to the three TextView controls.
Modifyactivity_values_resources_app.xml to appear as shown in Listing 4.10.

Listing 4.10. The Layout File activity_values_resources_app.xml on Applying Styles toTextView Controls

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/name_view"
style="@style/style1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_name"/>
<TextView
android:id="@+id/address_view"
style="@style/style2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_address" />
<TextView
android:id="@+id/message_view"
style="@style/style3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_message" />
</LinearLayout>
We can see that style1, style2, and style3 are applied to the
three TextView controlsname_view, address_view, and message_view, respectively. Hence, the
content of the firstTextView appears in green, serif font and 30sp in size. Similarly, the content of
the secondTextView appears in a blue foreground color, red background color, sans font, 30sp in
size, and the spacing (padding) between the text and the TextView on all four sides is 10dip.
The content in the third TextView appears in monospace font, green foreground color, black
background color, size30sp in and the text appears at the center of the TextView.
Note
The padding attribute value will be overridden by the gravity attribute, making the text appear at the center
of the TextView.
We don’t need any code in the Java activity file. So remove all the code that we have
been adding to it. That is, modify the Java file ValuesResourcesAppActivity.java to appear as
shown in Listing 4.11.

Listing 4.11. Code in the Java Activity File ValuesResourcesAppActivity.java

package com.androidunleashed.valuesresourcesapp;

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

public class ValuesResourcesAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_values_resources_app);
}
}

When the application is run, we get the output as shown in Figure 4.5.
Figure 4.5. The three TextViews with different styles applied to them

Applying Themes
We can apply the style element to an entire Activity or application by adding
the android:themeattribute to the Android manifest. For example, after we add
the android:theme attribute to the<activity> element in the Android manifest, all the attributes of
the style are applied to everyView within the Activity. Similarly, after we add
the android:theme attribute to the<application> element in the Android manifest, all the attributes
of the style are applied to all the activities in the application.
The AndroidManifest.xml file of our application ValuesResourcesApp originally appears as shown
in Listing 4.12.

Listing 4.12. Default Code in the AndroidManifest.xml File

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidunleashed.valuesresourcesapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".ValuesResourcesAppActivity"
android:label="@string/title_activity_values_resources_app" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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


</intent-filter>
</activity>
</application>
</manifest>
Let’s apply style3, which we defined in the styles.xml file, to the entire application by
modifying the android:theme attribute in AndroidManifest.xml file, as shown in bold in Listing
4.13.

Listing 4.13. Code in the AndroidManifest.xml File on Modifying the android:themeAttribute

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidunleashed.valuesresourcesapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/style3" >
<activity
android:name=".ValuesResourcesAppActivity"
android:label="@string/title_activity_values_resources_app" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
To see the impact of applying the style to the entire application, we need to remove
the styles in the layout file that were applied to the individual TextView controls. So,
modifyactivity_values_resources_app.xml to appear as shown in Listing 4.14.

Listing 4.14. The Layout file activity_values_resources_app.xml on Removing Styles

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/name_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_name" />
<TextView
android:id="@+id/address_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_address" />
<TextView
android:id="@+id/message_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_message" />
</LinearLayout>

After the application is run, we find that the content of all three Views appears
in monospace font,green foreground color, black background color, 30sp in size, and the text
appears at the center of the container, as shown in Figure 4.6.

Figure 4.6. The three TextViews styled by the application of a theme

We now know how to deal with values resources. Before we move onto drawable
resources, let’s have a quick look at one more form of string resources, known as the string
array.

Arrays
Arrays refer to a collection of values or elements. Arrays are known for their
capability of direct reference; that is, any element in an array can be referenced directly by
specifying itsindex/subscription value. Arrays are considered to be one of the most flexible data
sources for an application. Arrays can be in the form of strings or integers and are used for
storing the data of their respective data type.
Using String Arrays
As the name suggests, the string array provides an array of strings. Such a resource is
popularly used with selection widgets such as ListView and Spinner that need to display a
collection of selectable items to the user. To define a string array, we use the following
syntax:

<string-array name="array_name">
<item>text1</item>
<item>text2</item>
...
...
</string-array>
The name property acts as the resource ID and text1, text2, and so on represent the
elements of the string. The syntax for defining an integer array is shown here:

<integer-array name="array_name">
<item>number1</item>
<item>number2</item>
...
...
</integer-array>

First we learn to use string-array in an Android application, and then we learn to


use integer-array. To understand how string-array is defined and how it can be used to display a
list of items, let’s create a new Android project called StringArrayApp. In the strings resource
file strings.xml, define a string-array called fruits and assign a few strings to it. After we add
a string-array, the strings.xml file appears as shown in Listing 4.15.

Listing 4.15. Code in the strings.xml File on Adding a String Array

<resources>
<string name="app_name">StringArrayApp</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_string_array_app">StringArrayAppActivity</string>
<string-array name="fruits">
<item>Apple</item>
<item>Mango</item>
<item>Orange</item>
<item>Grapes</item>
<item>Banana</item>
</string-array>
</resources>

We can see that the string array fruits consists of five string elements,
namely Apple, Mango,Orange, Grapes, and Banana. Let’s make these string elements appear in
a TextView. Add aTextView to the layout file. The code appears as shown in Listing 4.16.

Listing 4.16. Code in the Layout File activity_string_array_app.xml on Adding theTextView Control

<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/fruits_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
A TextView with an ID fruits_view is added to the layout fileactivity_string_array_app.xml.
To access the elements of the string array and to display them via the TextView, we write the
code in the Java file StringArrayAppActivity.java as shown inListing 4.17.
Listing 4.17. Code Written in the Java Activity File StringArrayAppActivity.java

package com.androidunleashed.stringarrayapp;

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

public class StringArrayAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_string_array_app);
TextView fruitsView = (TextView)findViewById(R.id.fruits_view);
String[] fruitsArray = getResources().getStringArray(R.array.fruits);
String str = "";
for(int i = 0; i < fruitsArray.length; i++){
str += fruitsArray[i] + "\n";
}
fruitsView.setText(str);
}
}

The fruitsView TextView is accessed from the layout file main.xml and is assigned to
theTextView object fruitsView. Also, the string array fruits from the layout file is accessed and
assigned to the string array fruitsArray. That is, we can now access the string elements of the
string array from the layout file in the Java code via the string array fruitsArray. An empty
string, str, is created. When we use a for loop, each element of fruitsArray is accessed and
appended to the string str. A new-line character, \n, is added between every string element to
display them on separate lines. The string elements collected in the str element are assigned to
the TextView fruitsView for display. After the application is run, all the string elements are
displayed in theTextView, as shown in Figure 4.7.

Figure 4.7. The content of the string array displayed through a TextView

Let’s now take a look at creating and displaying integer array elements.
Using Integer Arrays
Creating an integer array is similar to creating a string array; the only difference is
that the tagstring-array, which we used for creating the string array, is replaced by integer-array.
The elements of the integer array are defined with the help of the child tag items, the same as
those used for string arrays. Let’s define an integer array consisting of a few elements in the
resource filestrings.xml file. After we define an integer array, the strings.xml file appears as
shown in Listing 4.18.

Listing 4.18. The strings.xml File on Defining an Integer Array

<resources>
<string name="app_name">StringArrayApp</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_string_array_app">StringArrayAppActivity</string>
<integer-array name="OddNumbers">
<item>1</item>
<item>3</item>
<item>5</item>
<item>7</item>
<item>9</item>
</integer-array>
</resources>
We display the integer array elements through a TextView. Since the integer array is
representing odd numbers, let’s change the resource ID of
the TextView in main.xml to oddnums_view. Theactivity_string_array_app.xml file now appears as
shown in Listing 4.19.

Listing 4.19. The Layout File activity_string_array_app.xml on Changing the Resource ID of


the TextView Control

<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/oddnums_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
The code that we write in the activity file StringArrayAppActivity.java to access the
elements of the integer array and to display them via TextView is shown in Listing 4.20.

Listing 4.20. Code Written in the Java Activity File StringArrayAppActivity.java to Access Array Elements

package com.androidunleashed.stringarrayapp;

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

public class StringArrayAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_string_array_app);
TextView oddNumsView = (TextView)findViewById(R.id.oddnums_view);
int[] oddNumsArray = getResources().getIntArray(R.array.OddNumbers);
String str = "";
for(int i = 0; i < oddNumsArray.length; i++){
str += oddNumsArray[i] + "\n";
}
oddNumsView.setText(str);
}
}

The oddNumsView TextView from the layout file is accessed and mapped to
the TextView objectoddNumsView. Also, the OddNumbers integer array that we defined in the
resource file strings.xmlis accessed and mapped to the integer array oddnumsArray. Through
a for loop, all the array elements are accessed and appended to an empty string, str.
Between each array element, a line feed character, \n, is inserted to make them appear on
separate lines. The content of the string str is then assigned to the TextView, oddNumsView for
display. After the application is run, we get the output shown in Figure 4.8.

Figure 4.8. The content of a numeric array displayed through a TextView

We have learned to use values resources. The next resource, drawable, is helpful in
displaying images in an Android application.

USING DRAWABLE RESOURCES


When it comes to displaying images, Android supports three common image formats:
PNG, JPG, and GIF. The images for the Android application are stored in the
directory res/drawable. Depending on the target platform chosen while creating a new
application, ADT either creates a single directory,res/drawable, or several: drawable-
ldpi, drawable-mdpi, drawable-hdpi, and drawable-xhdpi. Each directory is meant for storing images
of different screen resolutions. To support devices of different densities, we can store the
images of low, medium, high, and extra high resolutions in thedrawable-ldpi, drawable-
mdpi, drawable-hdpi, and drawable-xhdpi directories, respectively. The images with resolutions
of 320dpi, 240dpi, 160dpi, and 120dpi and sizes96x96px, 72x72px, 48x48px, and 36x36px are usually
stored in the res/drawable-xhdpi,res/drawable-hdpi, res/drawable-mdpi, and res/drawable-ldpi folders,
respectively. At runtime, depending on the density of the device on which the application is
run, Android automatically chooses the correct resolution image. For example, if the
application is running on a high-density device and the requested drawable resource is
available in the drawable-hdpi folder, Android uses it in the application. If Android doesn’t find
the image in the drawable-hdpi folder, it searches for the image in other directories to find the
closest match.
Displaying images is easy. We just put our image in the res/drawable folders and then
refer to it in the code. In this section, we learn to display images in an Android application.
Let’s create a new Android project called DispImageApp. As we said earlier, to display an
image in an application, the file needs to be added to the res/drawable folder. Android supports
images of almost all formats, but it prefers to use the PNG format. Copy a few images, for
example,bintupic.png of 96x96px, 72x72px, 48x48px, and 36x36px in size and resolutions
of 320dpi,240dpi, 160dpi, and 120dpi, respectively, into the res/drawable-xhdpi, res/drawable-
hdpi,res/drawable-mdpi, and res/drawable-ldpi folders, respectively. Remember, all image filenames
should be lowercase and contain only letters, numbers, and underscores. After we add images
to the res/drawable folders, the gen folder is regenerated where the R.java file resides.
TheR.java file includes a reference to the newly added image and hence can be used in the
layout file or other Java code. The syntax for referencing the image in the layout file is

@drawable/image_filename

In Java code, the image can be referenced using the following syntax:

R.drawable.image_filename

Remember, the image_filename in the syntax shown refers to the base name of the file,
that is, the filename without the extension. For example, the image file, bintupic.png, that we
just added to theres/drawable folder is accessed as @drawable/bintupic in the layout file and other
resources and as R.drawable.bintupic in the Java code. The extension of the image file, .png is
never used when referencing it.
Note
Any subdirectories inside /res/drawable are ignored.
To display the image, let’s add an ImageView control to the layout file. Write the code
in the layout fileactivity_disp_image_app.xml as shown in Listing 4.21.

Listing 4.21. The Layout File activity_disp_image_app.xml on Adding the ImageViewControl

<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">
<ImageView
android:id="@+id/image_toview"
android:src="@drawable/bintupic"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
We can see that an ImageView control is defined with the ID image_toview. To make our
image display through an ImageView control, we reference it via its src attribute. That is, we
use the following statement to assign or refer the image in the res/drawable folder:
android:src="@drawable/bintupic"

This statement loads the image bintupic.png, which we pasted into


the res/drawable folder. We don’t need to write any Java code for displaying the image. After
the application is run, the image is displayed, as shown in the Figure 4.9.

Figure 4.9. The image displayed through an ImageView control using a drawable resource

We can also specify the image for the ImageView control through Java code. To try
this, let’s remove the reference to the bintupic image in the ImageView control that we made
through the srcattribute:

android:src="@drawable/bintupic"

After we remove the image reference from the ImageView control, the layout
file,activity_disp_image_app.xml, appears as shown in Listing 4.22.

Listing 4.22. The Layout file activity_disp_image_app.xml on Removing the Image Reference from
the ImageView Control

<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">
<ImageView
android:id="@+id/image_toview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
If we run the application now, nothing appears on the screen, as no image has been
referenced by theImageView control. Let’s write the code in the Java activity
file DispImageAppActivity.java to assign an image to the ImageView control as shown in Listing
4.23.

Listing 4.23. The Java Activity File DispImageAppActivity.java

package com.androidunleashed.dispimageapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;

public class DispImageAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_disp_image_app);
ImageView image = (ImageView) findViewById(R.id.image_toview);
image.setImageResource(R.drawable.bintupic);
}
}

In the preceding Java file, the statement

ImageView image = (ImageView) findViewById(R.id.image_toview);

gets the ImageView control from the layout file and stores it in an ImageView object
called image.That is, the image is an ImageView object that now refers to the ImageView control
placed in the layout file.
Via the setImageResource() method used in this statement

image.setImageResource(R.drawable.bintupic);

the image bintupic.png stored in the res/drawable folder is assigned to the ImageView control for
display. After the application is run, we get the same output as shown previously in Figure
4.9.
We have now learned that the setImageResource() method can be used to change the
image of theImageView control dynamically at runtime. Let’s use this method to modify our
application so that it switches images when a button is clicked. When the button is clicked
again, the previous image is redisplayed in the ImageView control. The button that is most
suitable for this type of application is aToggleButton, which flips between two states.

SWITCHING STATES WITH TOGGLE BUTTONS


As the name suggests, the ToggleButton toggles between the two states, something like
a radio button. A ToggleButton can only be in one state out of two mutually exclusive states,
for example, Onand Off. To display a ToggleButton, we use the <ToggleButton> tag in the layout
file. To set the text for the button, the two attributes android:textOn and android:textOff are used.
The default values for the two attributes are ON and OFF, respectively. The following code
shows how to create a toggle button using the ToggleButton tag:

<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Play"
android:textOff="Stop" />

This code block defines a toggle button that shows the text Play in the On state and
shows Stop in theOff state.
Let’s create a new Android project called ToggleButtonApp. This project consists of
a TextViewand a ToggleButton. The TextView initially displays some text on startup. After we
select theToggleButton, the text displayed through TextView changes, and after we select
theToggleButton again, the previous text is redisplayed in the TextView control. So in all, we
need to define two controls in the layout file, TextView and a ToggleButton. After we define the
two controls, the code in the layout file activity_toggle_button_app.xml appears as shown
inListing 4.24.

Listing 4.24. Code in Layout File activity_toggle_button_app.xml on Adding


the TextViewand ToggleButton 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select the Play button"
android:id="@+id/response"/>
<ToggleButton android:id="@+id/playstop_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Play"
android:textOff="Stop"/>
</LinearLayout>
We can see that the TextView control is assigned the ID response and is set to display the
default text: Select the Play button. The ToggleButton is assigned the ID playstop_btn and is set to
display Play and Stop in the On and Off states, respectively. We want the text of
the TextViewcontrol to change on the click of the ToggleButton. To enable the ToggleButton to
switch text via the TextView control when it is clicked, we need to write some Java code in
theToggleButtonAppActivity.java file as shown in Listing 4.25.

Listing 4.25. Code Written in the Java Activity File ToggleButtonAppActivity.java

package com.androidunleashed.togglebuttonapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.view.View.OnClickListener;
import android.view.View;

public class ToggleButtonAppActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toggle_button_app);
final TextView resp = (TextView)this.findViewById(R.id.response);
final ToggleButton playStopButton = (ToggleButton)
findViewById(R.id.playstop_btn);
playStopButton.setChecked(true);
playStopButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (playStopButton.isChecked()) {
resp.setText("Stop button is toggled to Play button");
}
else {
resp.setText("Play button is toggled to Stop button");
}
}
});
}
}
In the preceding code, we can see that the response TextView and playstop_btn
ToggleButton are accessed from the layout file and are mapped to the TextView object resp and to
the ToggleButton object playStopButton, respectively. The ToggleButton is initially set to
thechecked (On) state on startup. An event handler OnClickListener is added to the ToggleButton
playStopButton. Its callback method, onClick(), is implemented, which executes when
theToggleButton is clicked. In the onClick() method, we check the state of the ToggleButton and
change the text displayed through the TextView control accordingly. That is, when
theToggleButton is in the On state, the text displayed through the TextView control is set to Stop
button is toggled to Play button. Similarly, when the ToggleButton is in the Off state, the text
displayed through the TextView is set to Play button is toggled to Stop button. The state of
the ToggleButton changes between the checked (On) and unchecked (Off) state on every click.
After the application is run, we get the output shown in Figure 4.10 (left). We can see
that theTextView control displays the default text Select the Play button, and the caption displayed
in the ToggleButton is Play. When the ToggleButton is selected, its caption changes to Stop, and
the text in the TextView changes to Play button is toggled to Stop button, as shown inFigure
4.10 (middle). When the ToggleButton is selecte again, the caption in the ToggleButtonchanges
back to Play, and the text in the TextView control changes to Stop button is toggled to Play button, as
shown in Figure 4.10 (right). That is, the caption in the ToggleButton, as well as the text in
the TextView controls, changes on every click of the ToggleButton.

Figure 4.10. (left) The ToggleButton and TextView on application startup, (middle) the text
on ToggleButton and TextView changes on selecting the ToggleButton, and (right) the original text
on ToggleButton reappears on clicking the ToggleButton again.

We can add the android:gravity and android:layout_gravity attributes to the <TextView>


and <ToggleButton> tags in the layout file to center the text in the TextView control and to align
the ToggleButton at the center position in respect to its container. The following statement
centrally aligns the text in the TextView control:

android:gravity="center"

The following statement makes the ToggleButton appear at the center of


the LinearLayoutcontainer:

android:layout_gravity="center"

We can also add a background image to the ToggleButton by adding


the android:backgroundattribute to the <ToggleButton> tag in the layout file. The following
statement sets theic_launcher.png image as the background image of the ToggleButton:

android:background="@drawable/ic_launcher"

The ic_launcher.png image is the built-in image resource provided by ADT that can be seen in
theres/drawable folder. After we add the android:layout_gravity and android:backgroundattributes,
the ToggleButton appears with a background image and at the center of
theLinearLayout container, as shown in Figure 4.11 (left). Figure 4.11 (middle and right) shows
how theToggleButton’s text and TextView’s text change with a click of the ToggleButton.

Figure 4.11. (left) The ToggleButton with background image applied and a TextView on application startup,
(middle) the text on the ToggleButton and TextView changes on selecting the ToggleButton—the background
image remains the same, and (right) the original text on the ToggleButton reappears on clicking
the ToggleButton again.

In Figure 4.11, we notice that, although the ToggleButton’s text changes on every click,
its background image remains the same. This is so because we defined the common
background of theToggleButton (for both of its states) through the android:background attribute.
To display different background images for the On and Off states of the ToggleButton, we need
to add two images to the application. Let’s paste two images called, play.png and stop.png, into
theres/drawable folders (res/drawable-xhdpi, res/drawable-hdpi, res/drawable-mdpi, andres/drawable-ldpi).
To make these pasted images display as background images in
theToggleButton control’s On and Off states, let’s add some Java code to
ourToggleButtonAppActivity.java file as shown in Listing 4.26. Only the statements in bold are
newly added code; the rest of the code is the same as we saw in Listing 4.25.

Listing 4.26. Code in the Java Activity File ToggleButtonAppActivity.java

package com.androidunleashed.togglebuttonapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.view.View.OnClickListener;
import android.view.View;

public class ToggleButtonAppActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toggle_button_app);
final TextView resp = (TextView)this.findViewById(R.id.response);
final ToggleButton playstopbutton = (ToggleButton)
findViewById(R.id.playstop_btn);
playstopbutton.setChecked(true);
playstopbutton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (playstopbutton.isChecked()) {
playstopbutton.setBackgroundDrawable(getResources().getDrawable(R.
drawable.play));
resp.setText("Stop button is toggled to Play button");
}
else {
playstopbutton.setBackgroundDrawable(getResources().getDrawable(R.
drawable.stop));
resp.setText("Play button is toggled to Stop button");
}
}
});
}
}
We can see that the newly added code accesses the Resources object through
the getResources()method, and the Drawable resources are accessed by supplying the resource ID
of the play.pngand stop.png images to the getDrawable() method. The images accessed are then
applied as the background of the ToggleButton’s On and Off states, respectively. Because we
don’t want any text to appear on top of the images of the ToggleButton, let’s remove the text of
the On and Off states. Modify the android:textOn and android:textOff attributes in
the <ToggleButton> tag of the layout file main.xml. We make the two attributes appear as shown
here:

android:textOn=""
android:textOff=""

These statements prevent the default text from appearing on the ToggleButton in
its On and Offstates. Now we replace the ic_launcher.png image with the play.png image by
setting the following attribute:

android:background="@drawable/play"
This attribute displays the play.png image on application startup. The layout
file main.xml on applying these changes appears as shown in Listing 4.27.

Listing 4.27. Code Written in the Layout File main.xml

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select the Play button"
android:id="@+id/response"
android:gravity="center" />
<ToggleButton android:id="@+id/playstop_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textOn=""
android:textOff=""
android:background="@drawable/play"/>
</LinearLayout>
After the application is run, we find the play.png image appears in
the ToggleButton (see Figure 4.12—left). After we select the Play button, the stop.png image
appears to represent theToggleButton’s Off state. Figure 4.12 (middle and right) shows how the
text displays when theTextView changes after clicking the ToggleButton.

Figure 4.12. (left) The ToggleButton with a background image (no text) and theTextView on application
startup, (middle) the background image of the ToggleButtonand TextView changes on selecting
the ToggleButton, and (right) the original background image reappears on the ToggleButton on clicking
the ToggleButton again.

CREATING AN IMAGE SWITCHER APPLICATION


We just learned how the ToggleButton works, so let’s use it to modify our earlier
application,DispImageApp, into an Image Switcher application. On startup, this application
initially displays an image through an ImageView control with a ToggleButton at the bottom of
the screen. When theToggleButton is clicked, the image displayed in the ImageView control
changes. After we click theToggleButton again, the previous image is redisplayed in
the ImageView control.
Because we want the application to switch images, we need to add one more image to
the application. Recall that we have already added an image, bintupic.png, in
the res/drawable folders of our application. Let’s add one more image called bintupic2.png by
dragging it to the res/drawablefolders (res/drawable-xhdpi, res/drawable-hdpi, res/drawable-mdpi,
andres/drawable-ldpi). Again, as expected, after we add image(s) to the res/drawable folder(s), the
Java class R.java is regenerated, allowing us to refer to the newly added image in the layout
file, as well as in Java code. After we add the two images, the application Package
Explorer appears as shown in Figure 4.13.

Figure 4.13. The Package Explorer window, showing the images dropped in theres/drawable folders

We want the application to show an image on startup (bintupic.png) through


the ImageViewcontrol, along with a ToggleButton at the bottom of the display. We need to
modify our layout file,main.xml, to do the following two things:
• Assign the bintupic.png image to an ImageView control to be displayed on startup.
• Add a ToggleButton to initiate image switching.
After we implement these tasks, our activity_disp_image_app.xml file appears as shown inListing
4.28.
Listing 4.28. Code in the Layout File activity_disp_image_app.xml on Adding aToggleButton and Assigning an
Image to the ImageView Control

<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="wrap_content">
<ImageView
android:id="@+id/image_toview"
android:src="@drawable/bintupic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />
<ToggleButton android:id="@+id/change_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Previous Image"
android:textOff="Next Image"
android:layout_gravity="center"
android:layout_marginTop="10dip" />
</LinearLayout>
We can see that the image_toview ImageView control is set to display bintupic.png. Below
theImageView control, a change_image ToggleButton is displayed at the center. TheToggleButton is
set to appear at a distance of 10dip from the ImageView control. The text of theToggleButton for
its On and Off states is set to Previous Image and Next Image, respectively. Now that we have all
the Views set, it’s time to add some actions to them. To enable theToggleButton to switch
images, we need to write some Java code in theDispImageAppActivity.java file as shown
in Listing 4.29.

Listing 4.29. Code Written in the Java Activity File DispImageAppActivity.java

package com.androidunleashed.dispimageapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.ToggleButton;
import android.view.View;
import android.view.View.OnClickListener;

public class DispImageAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_disp_image_app);
final ImageView image = (ImageView) findViewById(R.id.image_toview);
final ToggleButton changeButton=(ToggleButton)findViewById(R.id.change_image);
changeButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
if (changeButton.isChecked()) {
image.setImageResource(R.drawable.bintupic2);
}
else {
image.setImageResource(R.drawable.bintupic);
}
}
});
}
}
The image_toview ImageView control is accessed from the layout file and is mapped to
theImageView object image. Similarly, the ToggleButton control is accessed from the layout file
and is mapped to the ToggleButton object changeButton. An event handler, OnClickListener, is
added to the ToggleButton. Its callback method, onClick(), is implemented, which is executed
when the ToggleButton is clicked. In the onClick() method, we check the state of
theToggleButton and accordingly change the image being displayed through
the ImageView object. The state of the ToggleButton changes between checked and unchecked on
every click. After the application is run, we find that the first image, bintupic.png, is displayed
through the ImageViewcontrol along with the ToggleButton, and the text Next Image is displayed
at the bottom (seeFigure 4.14—left). When the ToggleButton is clicked, the image displayed
through the ImageViewcontrol switches to bintupic2.png, and the button text of
the ToggleButton changes to Previous Image, as shown in Figure 4.14 (right).

Figure 4.14. (left) An image displayed through the ImageView control with aToggleButton below it, and (right)
the image in the ImageView switches when theToggleButton is selected.

When the Previous Image button is clicked, the earlier image is redisplayed in
the ImageViewcontrol. What if the images being viewed are too long to accommodate in
a single screen? The solution is to apply the ScrollView control to scroll the images. Let’s learn
more.

SCROLLING THROUGH SCROLLVIEW


A ScrollView is a special type of control that sets up a vertical scrollbar in
a View container. This control is used when we try to display Views that are too long to be
accommodated in a single screen. The ScrollView can have only one child view, so usually
a View container layout is used as a child, which in turn contains other child controls that we
want to scroll through. All the child controls in the layout have one continuous scrollbar.
Let’s create a new Android project called ScrollViewApp. In this application, we place
three images, one below the other. It is obvious that all the three images cannot fit into a
single screen, so we use theScrollView control to scroll them vertically. First copy the three
images, bm1.png, bm2.png, andbm3.png, that we want to display in the res/drawable folders. To
display the three images on low, medium, high, and extra high resolution devices, copy their
low, medium, high, and extra high resolution versions into the res/drawable-ldpi, res/drawable-
mdpi, res/drawable-hdpi, and res/drawable-xhdpi folders, respectively.
Note
To display images on devices of different sizes and resolutions and to ensure that your app looks great on
any device, the 96x96px, 72x72px, 48x48px, and 36x36px images with resolutions
of 320dpi, 240dpi, 160dpi, and 120dpi, respectively, are copied into the res/drawable-xhdpi, res/drawable-
hdpi/, res/drawable-mdpi, andres/drawable-ldpi folders, respectively.
To display images in the application, we use the ImageView control and set
the android:srcattribute of each of them to refer to the files bm1.png, bm2.png, and bm3.png that
we copied into theres/drawable folder. The layout file activity_scroll_view_app.xml with the
threeImageView controls appears as shown in Listing 4.30.

Listing 4.30. Code in the Layout File activity_scroll_view_app.xml on Defining ThreeImageView Controls

<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" >
<ImageView
android:id="@+id/image_toview"
android:src="@drawable/bm1"
android:layout_width="200dip"
android:layout_height="250dip"
android:layout_gravity="center" />
<ImageView
android:id="@+id/image_toview2"
android:src="@drawable/bm2"
android:layout_width="200dip"
android:layout_height="250dip"
android:layout_gravity="center"
android:layout_marginTop="10dip" />
<ImageView
android:id="@+id/image_toview3"
android:src="@drawable/bm3"
android:layout_width="200dip"
android:layout_height="250dip"
android:layout_gravity="center"
android:layout_marginTop="10dip" />
</LinearLayout>
We didn’t use the ScrollView control in this code block, so you could see how images
appear without it. We will, however, add it later. We don’t have to write any code into the
activity fileScrollViewAppActivity.java. The default code is shown in Listing 4.31.
Listing 4.31. Default Code in the Java Activity File ScrollViewAppActivity.java

package com.androidunleashed.scrollviewapp;

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

public class ScrollViewAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scroll_view_app);
}
}
After the application is run, we see the output shown in Figure 4.15 (left). The first
two images are visible, and the third one is hidden. The application does not scroll, so there is
no way to see the hidden image. To add scrolling to the application, we add
the ScrollView control to the layout file and make it the parent of the
existing LinearLayout container. The ScrollView is set to wrap theLinearLayout, which contains the
three ImageView controls on which we want to apply the scrolling effect. After we add
the ScrollView control, the layout fileactivity_scroll_view_app.xml appears as shown in Listing
4.32.

Figure 4.15. (left) Two fixed images are displayed, and (right) scrolling images are displayed.

Listing 4.32. The Layout File activity_scroll_view_app.xml on Adding the ScrollViewControl

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollwid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical" >
<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" >
<ImageView
android:id="@+id/image_toview"
android:src="@drawable/bm1"
android:layout_width="200dip"
android:layout_height="250dip"
android:layout_gravity="center" />
<ImageView
android:id="@+id/image_toview2"
android:src="@drawable/bm2"
android:layout_width="200dip"
android:layout_height="250dip"
android:layout_gravity="center"
android:layout_marginTop="10dip" />
<ImageView
android:id="@+id/image_toview3"
android:src="@drawable/bm3"
android:layout_width="200dip"
android:layout_height="250dip"
android:layout_gravity="center"
android:layout_marginTop="10dip" />
</LinearLayout>
</ScrollView>

In the preceding code block, the attribute android:fillViewport used in the ScrollView control
needs an explanation.

Use of the android:fillViewport Attribute


When the size of the child control(s) is larger than the display, the ScrollView behaves
naturally by applying a scrolling effect to the child controls. However, if the size of the child
control(s) is smaller than the display, the ScrollView automatically shrinks to match the size of
its content and take as much space as the size of its content. When set to true,
the android:fillViewPort attribute makes the child control(s) of the ScrollView expand to the size
of the display. If the size of child control(s) is already larger than the display, the attribute has
no effect. We can see that in themain.xml file, the LinearLayout container holding the
three ImageView controls is made child of aScrollView control. The vertical scroller therefore
appears on the right side of the images, as shown in Figure 4.15 (right).
The ScrollView control is used for vertical scrolling. For horizontal
scrolling,HorizontalScrollView is used. The HorizontalScrollView acts the same as
the ScrollViewexcept that it scrolls child controls horizontally.
Note
You shouldn’t put a ListView inside a ScrollView because the ListView class implements its own scrolling
and is optimized for dealing with large lists. The gestures onListView will not be received by ListView, but
by the parent ScrollView.
We just learned how to display images in Android applications. Next we see how to
play audio files.
PLAYING AUDIO
In this section, we learn to play audio in Android applications. We also learn the
methods used to pause and resume the audio. Let’s make a new Android project
called PlayAudioApp. The audio that we want to play needs to be added to this application.

Adding Audio to the Application


The audio file that we want to play must be located in the res/raw folder of our
application. The rawfolder isn’t created automatically, so we need to create it manually.
The raw folder is a special folder that is not processed at all; hence the content of the files
copied in this folder is retained. Right-click the res folder in the Package Explorer window and
select New, Folder. In the dialog box that opens, enter the name of the new folder as raw and
click the Finish button.
In the raw folder, let’s copy an audio file called song1.mp3. The Java class R.java file is
automatically regenerated after the audio file is added to the application allowing us to access
it. Theres folder looks like Figure 4.16.

Figure 4.16. The newly added raw folder showing the audio, song1.mp3, which was added to it

In this application, we want to display a TextView and


a Button control. TextView displays instruction(s), and the Button control initiates an action. To
add the two controls, write the code in the layout file activity_play_audio_app.xml as shown
in Listing 4.33.

Listing 4.33. The Layout File activity_play_audio_app.xml on Adding the TextView andButton 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Playing Audio" />
<Button android:id="@+id/playbtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Play" />
</LinearLayout>
The TextView is set to display the text Playing Audio. The ID and the caption assigned to
theButton control are playbtn and Play, respectively. To play the audio when the button is
clicked, write the code as shown in Listing 4.34 into the activity file PlayAudioAppActivity.java.

Listing 4.34. Code Written in the Java Activity File PlayAudioAppActivity.java

package com.androidunleashed.playaudioapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.media.MediaPlayer;

public class PlayAudioAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_audio_app);
Button playButton = (Button) findViewById(R.id.playbtn);
playButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
MediaPlayer mp =
MediaPlayer.create(PlayAudioAppActivity.this,R.raw.song1);
mp.start();
}
});
}
}
The playbtn Button control is captured from the layout and mapped to
the Button objectplayButton. An event handler, OnClickListener, is added to the playButton object.
Its callback method, onClick(), is implemented, which is executed when the playButton is
clicked. In theonClick() method, we create an instance, mp, of the MediaPlayer by calling
theMediaPlayer.create() method. To the MediaPlayer instance mp, we pass the reference of our
MP3 song, song1.mp3, that we placed in the raw folder. Finally, we call the
MediaPlayer’s start()method to play the song. After the application is run, we get
a TextView showing the text Playing Audio and a Button control with the text Play, as shown
in Figure 4.17. When the Play button is clicked, the audio, song1.mp3, is played.
Figure 4.17. The TextView and a Play Button control on application startup

We can control the volume of the audio with the volume switches on the side of the
Android emulator. And we can also display an image on the Button control by adding the
following attributes to the<Button> element:
• android:drawableTop—The image is displayed above the button text.
Example:

android:drawableTop="@drawable/ic_launcher"
This statement displays the ic_launcher.png image above the button text, as shown in Figure
4.18(upper-left).
• android:drawableBottom—The image is displayed below the button text as seen in Figure
4.18 (upper-right).
• android:drawableLeft—The image is displayed to the left of the button text as shown
in Figure 4.18(bottom-left).
• android:drawableRight—The image is displayed to the right of the button text as shown
in Figure 4.18(bottom-right).

Figure 4.18. (upper-left) The image drawn above the button text, (upper-right) the image drawn below the
button text, (bottom-left) the image drawn to the left of the button text, and (bottom-right) the image drawn to
the right of the button text

PlayAudioApp works fine, but it doesn’t have a Stop or Pause button to stop and resume
playing the audio. To switch the status of the audio from play to stop and vice versa, we
replace the Button control with the ToggleButton control. The layout
file activity_play_audio_app.xml now appears as shown in Listing 4.35.

Listing 4.35. The Layout File activity_play_audio_app.xml on Replacing Button with theToggleButton Control

<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:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/response"/>
<ToggleButton android:id="@+id/playstop_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Stop"
android:textOff="Play"
android:layout_gravity="center" />
</LinearLayout>
We can see that a playstop_btn ToggleButton is defined and assigned the
text Stop and Playfor its On and Off states. The ToggleButton is set to appear at the center of the
LinearLayout container through the android:layout_gravity="center" attribute. Similarly, the text
in theTextView control is aligned at the center through the android:gravity="center" attribute. Also,
an ID response is assigned to the TextView so that we can access it and can change its text
dynamically at runtime. To stop and resume the audio with a click of the ToggleButton, we
write the Java code as shown in Listing 4.36 in the PlayAudioAppActivity.java file.

Listing 4.36. Code Written in the Java Activity File PlayAudioAppActivity.java

package com.androidunleashed.playaudioapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ToggleButton;
import android.view.View;
import android.widget.TextView;
import android.media.MediaPlayer;
import android.view.View.OnClickListener;

public class PlayAudioAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_audio_app);
final TextView response = (TextView)this.findViewById(R.id.response);
response.setText("Select Play button to play audio");
final MediaPlayer mp = MediaPlayer.create(PlayAudioAppActivity.this,R.raw.song1);
final ToggleButton playStopButton = (ToggleButton)
findViewById(R.id.playstop_btn);
playStopButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (playStopButton.isChecked()) {
response.setText("Select Stop button to stop audio");
mp.start();
}
else {
response.setText("Select Play button to play audio");
mp.pause();
}
}
});
}
}
The TextView and ToggleButton controls with the IDs response and playstop_button are
accessed from the layout file and mapped to
the TextView and ToggleButton objects responseand playStopButton, respectively. The TextView is
set to display the text Select Play button to play audio. An instance, mp, of the MediaPlayer is created
by calling MediaPlayer’s create()method. To the create() method, the reference of the MP3
song, song1.mp3, which we stored in theraw folder, is passed. An event handler, OnClickListener,
is added to the ToggleButton object. Whenever, the ToggleButton is clicked, its callback
method, onClick(), is executed. In theonClick() method, we check the status of the ToggleButton.
If the ToggleButton is in the Onstate, we call the MediaPlayer’s start() method to play the audio
and set the text of the TextView toSelect Stop button to stop audio to inform the user that if
the ToggleButton is clicked, the audio is stopped. If the ToggleButton is in the Off state, the
MediaPlayer’s pause() method is called to stop the audio. The text of the TextView is set
to Select Play button to play audioto inform the user that if the ToggleButton is clicked again, the
audio resumes. After the application is run, we get a TextView and a ToggleButton shown
in Figure 4.19 (left). The text on theToggleButton, Play, and the text shown through
the TextView, Select Play button to play audio, directs the user to click the ToggleButton if she wants
to play the audio. After we select the ToggleButton, the audio begins playing, the text on
the ToggleButton changes to Stop, and the text displayed through the TextView is changed
to Select Stop button to stop audio, as shown in Figure 4.19 (right). If we select
the ToggleButton again, the audio stops and the text on the ToggleButton and that
of TextView changes to that shown in Figure 4.19 (left).

Figure 4.19. (left) The TextView and a Play Toggle Button control—audio plays on selecting the ToggleButton,
and (right) the text on the ToggleButton and TextViewchanges on selecting the ToggleButton.

The preceding application is almost perfect, but let’s change it so that it


displays Play and Stopimages in the ToggleButton instead of plain text. It’s easy to do.
We need to add two images, play.png and stop.png, to the four res/drawable folders of this project.
After we add the two images, the Java class, R.java, is regenerated containing the reference to
the two images, so we can access them through code.
Because we want only the play and stop images to appear in the ToggleButton without
text, we need to reset the android:textOn and android:textOff attributes of the <ToggleButton> tag in
the layout file main.xml, as shown here:

android:textOn=""
android:textOff=""

These statements remove any text in the ToggleButton that is displayed in its On and Off states.
Also, we need to use the android:background attribute to display the play.png image in
theToggleButton on startup. To do this, we need to add the following statement in
the<ToggleButton> tag:

android:background="@drawable/play"

After we apply these modifications, the layout file activity_play_audio_app.xml appears as shown
in Listing 4.37. Only the code in bold is modified; the rest is the same as we saw in Listing
4.35.

Listing 4.37. Code in the Layout File activity_play_audio_app.xml on Adding the Background Image to
the ToggleButton

<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:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/response"/>
<ToggleButton android:id="@+id/playstop_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn=""
android:textOff=""
android:layout_gravity="center"
android:background="@drawable/play" />
</LinearLayout>
To change the background image of the ToggleButton from play.png to stop.png when
clicked, we need to add two statements to the Java activity file PlayAudioAppActivity.java, as
shown inListing 4.38. Only the statements shown in bold are the newly added code; the rest
of the code is the same as we saw in Listing 4.36.

Listing 4.38. Code in the Java Activity File PlayAudioAppActivity.java

package com.androidunleashed.PlayAudioApp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ToggleButton;
import android.view.View;
import android.widget.TextView;
import android.media.MediaPlayer;
import android.view.View.OnClickListener;

public class PlayAudioAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_audio_app);
final TextView response = (TextView)this.findViewById(R.id.response);
response.setText("Select Play button to play audio");
final MediaPlayer mp = MediaPlayer.create(PlayAudioAppActivity.this,R.raw.song1);
final ToggleButton playStopButton = (ToggleButton)
findViewById(R.id.playstop_btn);
playStopButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (playStopButton.isChecked()) {
response.setText("Select Stop button to stop audio");
playStopButton.setBackgroundDrawable(getResources().getDrawable(R.
drawable.stop));
mp.start();
}
else {
response.setText("Select Play button to play audio");
playStopButton.setBackgroundDrawable(getResources().getDrawable(R.
drawable.play));
mp.pause();
}
}
});
}
}
We can see that the newly added code allows access to the stop.png and play.png images
from the drawable resources by supplying the image filenames to the getDrawable() method of
theResources object. Depending on the current state of the ToggleButton (On or Off), the accessed
images are assigned to appear as its background. After the application is run, we see
the TextView and a ToggleButton showing the play.png image (Figure 4.20—left). The text in
the TextView control tells the user that when the Play button is clicked, an audio file is played.
The audio begins playing, and the ToggleButton’s background changes from play.png to stop.png.
The text in TextViewalso changes to tell the user that the Stop button can be pressed to stop the
audio, as shown in Figure 4.20 (right).

Figure 4.20. (left) The TextView and a Toggle Button control representing an audio play button—audio plays
when selecting the ToggleButton, and (right) theToggleButton’s image changes to a Stop button when selected,
informing the user that audio stops if selected again.

Note
If we want to play a song available on the Internet, we can use its URI.
Let’s now see how video can be run in an Android application.
PLAYING VIDEO
To play video in an application, Android provides a VideoView control, which, along
with the MediaController, provides several buttons for controlling video play. These buttons
allow us to play, pause, rewind, and fast-forward the video content displayed via
the VideoView control. To understand the steps for playing a video, let’s create a new Android
project called PlayVideoApp. We can play a video that is available on the Internet or one that is
loaded onto an SD card of our device or emulator.
Note
Unlike audio, the video doesn’t play when placed in the raw folder. Instead it needs to be placed in
the SDCARD folder.

Loading Video onto an SD Card


An emulator must be running while loading video onto an SD Card. Switch on the
emulator by selecting the Window, AVD Manager option. Select the demoAVD virtual device—
the one we created in Chapter 1, “Introduction to Android”—and select the Start button. We
get a dialog box showing the Launch Options of the emulator. Select the Launch button to run
the emulator. Remember, only the emulator with an sdcard option should be run. After you
select the Launch button, the emulator starts. Close the AVD Manager dialog. To load a video
onto an SD card, follow these steps:
1. Open the DDMS perspective by selecting the Window, Open Perspective, DDMS option.
2. In the DDMS perspective, open the File Explorer by selecting Window, Show View, File Explorer.
3. If you can’t see the running emulator anywhere, open the Devices view by
selecting Window, Show View, Devices option. We are able to see all the running emulators, and
we can select the one that we want to use for playing the video.
4. In the File Explorer view, we see different folders and files in the emulator (see Figure 4.21).

Figure 4.21. The DDMS showing different folders in the emulator through the File Explorer
Navigate the tree and expand the mnt node. In the mnt node, select the sdcard node. If
you hover your mouse over the two buttons on the top right side of File Explorer, you see the
messages Pull a file from the device and Push a file onto the device. Figure 4.22 (left) shows these
marked with ellipses.

Figure 4.22. (left) The folders in the emulator along with the buttons to pull video from and push it to
the sdcard, and (right) the File Explorer displaying the video,video.mp4, inserted onto the sdcard of the
emulator

Click the button Push a file onto the device. We see a dialog box for choosing a video
from the disk drive. After selecting a video, select the OK button to load the selected video
onto the SD Card.Figure 4.22 (right) shows the File Explorer after video.pm4 has been loaded
onto the SD card.
Now we can go ahead and add a VideoView control to our layout file to view the
loaded video. After we define the VideoView and Button controls in activity_play_video_app.xml, it
appear as shown in Listing 4.39.

Listing 4.39. Code in the Layout File activity_play_video_app.xml on Adding VideoViewand 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" >
<VideoView android:id="@+id/video"
android:layout_width="320dip"
android:layout_height="240dip"/>
<Button android:id="@+id/playvideo"
android:text="Play Video"
android:layout_height="wrap_content"
android:layout_width="match_parent" />
</LinearLayout>
We can see that a VideoView and a Button control have been added to the application, where
theVideoView widget is used for displaying video, and the Button control plays the video when
selected.
To assign the video to the VideoView control, which is used to perform a variety of functions,
write the code as shown in Listing 4.40 in the Java activity file PlayVideoAppActivity.java.

Listing 4.40. Code in the Java Activity File PlayAudioAppActivity.java

package com.androidunleashed.playvideoapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.MediaController;
import android.widget.VideoView;

public class PlayVideoAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_video_app);
Button playVideoButton=(Button)findViewById(R.id.playvideo);
playVideoButton.setOnClickListener(new OnClickListener() {
public void onClick(View view){
VideoView videoView=(VideoView)findViewById(R.id.video);
videoView.setMediaController(new
MediaController(PlayVideoAppActivity.this));
videoView.setVideoPath("sdcard/video.mp4");
videoView.requestFocus();
videoView.start();
}
});
}
}

We capture the VideoView control from the layout and map it to the videoView object.
Then we use a MediaController and set it the media controller of the videoView object.
The videoView object is used for displaying video content and the button controls that enable
us to perform play, pause, rewind, or fast-forward actions on the video. A MediaController
provides these buttons. Hence the VideoView’s media controller is set by
calling setMediaController() to display the different button controls. Then, we use
the setVideoPath() method of the VideoViewobject to refer to an SD card (sdcard) for
the video.mp4 file. We can also use setVideoURI()method to access the video from the Internet.
After setting the focus to the VideoView control throughrequestFocus() method, we use
its start() method to start the video.
Run the application. We get the output showing a button, Play Video, as shown
in Figure 4.23 (left). After we select the Play Video button, the video is displayed in
the VideoView control, along with the button controls displayed via the MediaController, as
shown in Figure 4.23 (right). The buttons enable stop, resume, rewind, and fast-forward. The
progress bar at the bottom shows our location in the video.

Figure 4.23. (left) The button control with the caption, Play Video, displayed on application startup, and (right)
the video displayed in the VideoView control on selecting the Play Video button. Video control buttons appear
at the bottom via the MediaController.

DISPLAYING PROGRESS WITH PROGRESSBAR


Certain tasks, such as downloading a file, installing software, executing complex
queries, and playing audio and video, take time to execute. While executing such tasks, we
need to continually inform the user about the task progress by displaying a progress indicator.
The ProgressBar is a control commonly used for displaying the progress of execution of tasks.
The default mode of theProgressBar view is a circular indicator that animates to show that a
task is active but doesn’t show actual progress. This icon is used when there is no specific
duration for completion of the task. A more informative solution is a horizontal progress bar
that displays an indicator showing the amount of a task that is completed (or is left to
complete). To make the ProgressBar display in the form of a horizontal bar, set its style
attribute to @android:style/Widget.ProgressBar.Horizontal, as shown in this example:

<ProgressBar android:id="@+id/progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal" />

The following styles can be applied to the ProgressBar:


• Widget.ProgressBar.Horizontal
• Widget.ProgressBar.Small
• Widget.ProgressBar.Large
• Widget.ProgressBar.Inverse
• Widget.ProgressBar.Small.Inverse
• Widget.ProgressBar.Large.Inverse
The ProgressBar for Widget.ProgressBar.Horizontal, Widget.ProgressBar.Small,
andWidget.ProgressBar appears as shown in Figure 4.24 (left, middle, and right, respectively).
Figure 4.24. (left) Horizontal style ProgressBar, (middle) small style ProgressBar, and (right) large
style ProgressBar

The inverse style is used when our application uses a light-colored theme, such as a
white background. The minimum value of the ProgressBar is by default 0. The maximum value
of theProgressBar is set by the android:max attribute. For example, the following statement, when
applied to the ProgressBar control in the layout file, sets the maximum value of the ProgressBarto
100:

android:max="100"

We can also set the maximum value of the ProgressBar through a setMax() Java method. The
following code sets the maximum value of the ProgressBar to 100:

progressBar.setMax(100);

To display progress through an indicator in the ProgressBar control, we call


the setProgress()method of the ProgressBar class, passing in an integer value to indicate the
progress. For example, the following statement sets the progress to 60, making the indicator
appear at the 60 percent complete mark:

progressBar.setProgress(60);

where progressBar is an object that represents the ProgressBar control.


Let’s create an Android project to understand the ProgressBar. Name the new Android
projectProgressBarApp. In this application, we play an audio, and the ProgressBar displays the
progress of the audio, showing how much has been played and how much is left. For this
application, we use aTextView, a ToggleButton, and a ProgressBar control. The TextView control is
used to have the user select the ToggleButton to play or stop the audio. The ToggleButton plays
and stops the audio, and a horizontal bar ProgressBar displays the audio’s progress. After we
add theToggleButton and ProgressBar controls, the layout file activity_progress_bar_app.xmlappears
as shown in Listing 4.41.

Listing 4.41. Code Written in Layout File activity_progress_bar_app.xml on Adding


theToggleButton and ProgressBar Controls

<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" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/response"/>
<ToggleButton android:id="@+id/playstop_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn=""
android:textOff=""
android:layout_gravity="center"
android:background="@drawable/play" />
<ProgressBar android:id="@+id/progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_marginTop="20dip" />
</LinearLayout>

To display Play and Stop images in the ToggleButton (see Figure 4.25), we copy the
imagesplay.png and stop.png to the res/drawable folders. For playing audio, create a folder
called rawin the res folder and then copy the audio file song1.mp3 into it.

Figure 4.25. (left) ProgressBar on application startup, and (right) ProgressBarshowing the duration of audio
played

To play and stop the audio with the ToggleButton control and to display the progress of
the audio in the ProgressBar control, write the code as shown in Listing 4.42 in the activity
fileProgressBarAppActivity.java.

Listing 4.42. Code Written in the Activity File ProgressBarAppActivity.java

package com.androidunleashed.progressbarapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ToggleButton;
import android.view.View;
import android.widget.TextView;
import android.media.MediaPlayer;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.os.Handler;

public class ProgressBarAppActivity extends Activity {


MediaPlayer mp;
ProgressBar progressBar;
private final Handler handler = new Handler();

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress_bar_app);
final TextView response = (TextView)this.findViewById(R.id.response);
response.setText("Select Play button to play audio");
progressBar=(ProgressBar)findViewById(R.id.progressbar);
mp = MediaPlayer.create(ProgressBarAppActivity.this,R.raw.song1);
final ToggleButton playStopButton = (ToggleButton)
findViewById(R.id.playstop_btn);
progressBar.setProgress(0);
progressBar.setMax(mp.getDuration());

playStopButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (playStopButton.isChecked()) {
response.setText("Select Stop button to stop audio");
playStopButton.setBackgroundDrawable(
getResources().getDrawable(R.drawable.stop));
mp.start();
updateProgressBar();
}
else {
response.setText("Select Play button to play audio");
playStopButton.setBackgroundDrawable(
getResources().getDrawable(R.drawable.play));
mp.pause();
}
}
});
}

private void updateProgressBar() {


progressBar.setProgress(mp.getCurrentPosition());
if (mp.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
updateProgressBar();
}
};
handler.postDelayed(notification,1000);
}
}
}
In this code block, we can see that the TextView, ProgressBar, and ToggleButton controls
with the IDs response, progressbar, and playstop_btn are accessed from the layout file main.xmland
assigned to their respective button objects (response, progressBar, and playStopButton).
The TextView is initially set to display Select Play button to play audio to tell the user what is
supposed to be done. An instance (mp of the MediaPlayer) is created by calling
theMediaPlayer’s create() method. The MP3 song reference, song1.mp3, which we stored in
the rawfolder, is passed to the create() method. The minimum value of the ProgressBar control is
set to 0, and its maximum value is set equal to the duration of the audio.
An object handler of the Handler class is made, as we use it to send and process
a Runnable object.Handler is the preferred threading technique used to perform tasks in the
background. We talk about the threading technique in detail in Chapter 13, “Creating and
Consuming Services.” A Handler object processes Message and Runnable objects associated with
the current thread’s MessageQueue. AMessageQueue is a queue of messages (in FIFO order) where
each message is a task that we want to be performed. When a message or runnable object is
passed to the Handler, it is saved into the message queue. The UI thread pulls the message or
runnable object from the queue and executes it. The UI thread is the main thread that is
automatically created when an application is launched and is the one that handles events
related to the widgets or controls used in the application.
An event handler, OnClickListener, is added to the ToggleButton object playStopButton.
Whenever the ToggleButton is clicked, its callback method, onClick(), is executed.
In the onClick() method, we check the status of the ToggleButton. If the ToggleButton is set to
the On state, we call the MediaPlayer’s start() method to play the audio and set the TextView to
display the text Select Stop button to stop audio to tell the user that if the ToggleButtonis pressed
again, the audio will be stopped. The image stop.png from drawable resources is accessed and
displayed as the background image of the ToggleButton
playStopButton. Theupdateprogressbar() method is called to update the ProgressBar indicator.
In the updateprogressbar() method, we update the progress bar indicator to set it at the
location decided by the MediaPlayer instance, mp. That is, the duration of audio played is
displayed by updating the progress bar indicator periodically. For periodic execution of
theupdateprogressbar() method, we use threading.
A Runnable object notification is created and added to the message queue through
thepostDelayed() method of the handler object. The runnable object is scheduled to run after 1000
milliseconds. The runnable object is run on the thread to which this handler is attached—the
main UI thread. The run() method, which is executed after every 1000 milliseconds, calls
theupdateprogressbar() method to update the progress bar indicator periodically.
If the ToggleButton is in the Off state, the MediaPlayer's pause() method is called to stop the audio.
The text of the TextView is set to display the message Select Play button to play audio to tell the
user that, on clicking the ToggleButton again, the audio resumes playing. The image, play.png,
from drawable resources is accessed and displayed as the background image of
theToggleButton playStopButton.
After the application is run, we get a TextView, a ToggleButton, and a ProgressBar, as
shown inFigure 4.25 (left). The text message shown through TextView, Select Play button to play
audio, directs the user to click the ToggleButton to play the audio. After the user selects
theToggleButton, the audio begins playing, and the image on the ToggleButton changes to display
the stop.png file, and the text displayed through the TextView changes to Select Stop button to stop
audio. The indicator in the ProgressBar shows the duration of the audio played, as shown
in Figure 4.25 (right).

USING ASSETS
We have already seen how resources are used in Android applications. The external
files containing information such as strings, images, and audio that reside in the res/ folder are
considered resources. Besides the res/ directory, Android provides another directory, assets/,
where we can keep asset files to be included in our application. The difference between
resources and assets is that the resources are accessible in an Android application through the
resource IDs generated in the R.java file. Android automatically generates an R.java file that
contains the IDs of the resources found in res/folder, making it possible to access them
through Java code. Content placed in the assets/ directory is maintained in raw file format, and
no IDs are generated for these files. To read the content from theassets/ folder in an Android
application, we use the AssetManager, which reads the content from the external files in the
form of a stream of bytes.
In the application that we are going to create as an example, we add a text file asset.
The content in the text file added to the assets folder is accessed using the AssetManager and is
displayed in aTextView. Launch the Eclipse IDE and create a new Android project
called AssetsApp. Add a file called info.txt (it should obviously contain some text) to the project
by copying and pasting it into the assets folder in the Package Explorer window. Because we
want the content of info.txt be displayed through a TextView, let’s modify the layout
file activity_assets_app.xml to appear as shown in Listing 4.43.

Listing 4.43. Code in Layout File activity_assets_app.xml on Adding the TextViewControl

<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" >
<TextView
android:id="@+id/file_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15dip"
android:textStyle="bold" />
</LinearLayout>
We can see that the layout file activity_assets_app.xml contains a file_view
TextViewcontrol. The content to be displayed via TextView is set to appear in bold, 15dip text.
To read the content from the file, info.txt is placed in the assets folder and is displayed via
the TextViewcontrol. Code shown in Listing 4.44 is written in the Java activity
file AssetsAppActivity.java for reading the content from the file placed in the assets folder and
displaying it through the TextViewcontrol.

Listing 4.44. Code in the Java Activity File AssetsAppActivity.java

package com.androidunleashed.assetsapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import java.io.InputStream;
import android.content.res.AssetManager;
import java.io.IOException;

public class AssetsAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_assets_app);
TextView fileView=(TextView)findViewById(R.id.file_view);
InputStream input;
AssetManager assetManager = getAssets();
try {
input = assetManager.open("info.txt");
int fileSize = input.available();
byte[] buffer = new byte[fileSize];
input.read(buffer);
input.close();
String textForm = new String(buffer);
fileView.setText(textForm);
} catch (IOException e) {
fileView.setText("Some exception has occurred");

}
}
}
We can see in this code block that the TextView is accessed from the layout file and is
mapped to theTextView object fileView. Because the assets are read using an AssetManager, we
get a reference to the AssetManager instance by calling the getAssets() method. Basically,
the getAssets()method opens the Assets folder and returns a handle to this folder. To read
content from a file, we need an InputStream object, so the open() method of
the AssetManager class is called, passing the filename info.txt to it as the parameter.
The open() method opens the file info.txt in theassets folder and returns it in the form of
the InputStream, which is assigned to the InputStreaminstance input. The size of the file is
computed by calling an available() method on theInputStream class. A buffer equal to the file
size is defined, and the file content is read via theInputStream object into the buffer.
The InputStream object is closed. The file content in the form of bytes stored in the buffer is
converted into a string and is assigned to the TextView control for display. After the
application is run, we find the content of the file info.txt is displayed throughTextView, as
shown in Figure 4.26.

Figure 4.26. The content of the file in the assets folder displayed via TextView
Unit – IV
Using Selection Widgets and Debugging
As the name suggests, selection widgets refers to the group controls that display a list
of choices from which users select items. To constrain users to enter the correct data type or
within a specific range and also to show the valid values, lists and drop-down lists are
commonly used in applications. Lists and drop-down lists are
called ListView and Spinner controls in Android. Besides ListView andSpinner, we discuss two
more selection widgets in this chapter: AutoCompleteTextView andGridView.
Let’s begin our journey with the first selection widget, the ListView.

USING LISTVIEW
A ListView is used to display a list of vertically scrolling items, allowing users to select
one or more of them. Several attributes can be used to configure this control. Some of them
are listed in Table 5.1.

Table 5.1. List of Attributes Used to Configure the ListView Control

A sample ListView control may appear as follows:


<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="@array/fruits"
android:choiceMode="singleChoice"
android:drawSelectorOnTop="false"
android:transcriptMode="normal" />

This sample defines a ListView with the ID list, whose items are populated by the string
arrayfruits. Only one item is selectable from the ListView. No selector appears on the top of
theListView, and it also scrolls to the bottom when a new item is added to the data source.
For creating ListView controls, we can use either of the following methods:
• The regular Activity base class
• An activity that extends android.app.ListActivity
Note
The ListActivity class already contains a ListView; hence while extending this class, we don’t need to
define the ListView control in the layout file.
Let’s begin with creating a ListView through a regular Activity base class.

Creating a ListView with an Activity Base Class


In both cases, whether we are creating a ListView by extending the Activity class or
theListActivity class, the ListView can be populated by one of the following two methods:
• By ListView through a string resource
• By ListView through Adapter
Populating ListView Through String Resource
To understand how a ListView is populated through string resources, let’s create a new
Android project called ListViewApp. In this application, we use two
controls: ListView and TextView.ListView is populated through string resources to display a list
of items for the user to select from. The item or option selected from the ListView is displayed
via the TextView control.
Open the string resource file /res/values/strings.xml, and add a string-array structure
called fruits that lists various fruits that we want to display via the ListView control. After we
add astring-array, the strings.xml file appears as shown in Listing 5.1.

Listing 5.1. The strings.xml File After Adding the Strings Array

<resources>
<string name="app_name">ListViewApp</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_list_view_app">ListViewAppActivity</string>
<string-array name="fruits">
<item>Apple</item>
<item>Mango</item>
<item>Orange</item>
<item>Grapes</item>
<item>Banana</item>
</string-array>
</resources>
The string resource app_name is the default string resource meant for displaying the
application name in the title bar while running the application. The string-array fruits is the one
that defines the array elements that we use to populate the ListView control.
After we define fruits, the next step is to define the two controls, ListView and TextView, in the
layout file. Open the layout file main.xml and define ListView and TextView. The code written
intoactivity_list_view_app.xml appears as shown in Listing 5.2.

Listing 5.2. The Layout File activity_list_view_app.xml After Defining the ListView andTextView 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="wrap_content">
<ListView android:id="@+id/fruits_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="@array/fruits"
android:drawSelectorOnTop="false"/>
<TextView
android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
We can see that the ListView and TextView controls are assigned the resource
IDs fruits_listand selectedopt, respectively. To populate the ListView, the string-array fruits is
assigned to the ListView through the android:entries attribute. That is, the android:entries attribute
in the layout XML file is used for populating ListView from the string
resource. Theandroid:drawSelectorOnTop attribute is set to false, because we don’t want the selector
to be drawn over the selected item.
To display the option selected from the ListView in the TextView control, we need to
access thestring-array TextView and attach an event listener to the ListView to sense for the
occurrence of an event on it. To do this, we write the code shown in Listing 5.3 into the Java
activity fileListViewAppActivity.java.

Listing 5.3. Code Written into the Java Activity File ListViewAppActivity.java

package com.androidunleashed.listviewapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.ListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.view.View;

public class ListViewAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_app);
final String[] fruitsArray = getResources().getStringArray(R.array.fruits);
final TextView selectedOpt=(TextView)findViewById(R.id.selectedopt);
ListView fruitsList = (ListView)findViewById(R.id.fruits_list);
fruitsList.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View v, int position,
long id)
{
selectedOpt.setText("You have selected "+fruitsArray[position]);
}
});
}
}
The string-array fruits from the resource file strings.xml is accessed and assigned to the
string array fruitsArray. Similarly, the TextView selectedopt and the ListView fruits_list are captured
from the layout file and assigned to the objects selectedOpt andfruitsList, respectively. To take
an action when an item is selected from the ListView, thesetOnItemClickListener() method is
passed a new AdapterView.OnItemClickListener. This anonymous instance implements
the onItemClick() callback method, which is executed when an item is selected from
the ListView. In the onItemClick() method, we find the index location (position) of the selected
item, use it to access the array element from the string array fruitsArray, and display it through
the TextView object selectedOpt.
When the application is run, we see the list of fruits defined in the string-array fruits is
displayed in the ListView control as shown in Figure 5.1 (left). When an item is selected from
theListView, it is displayed through the TextView, as shown in Figure 5.1 (right).

Figure 5.1. Options displayed via the string array (string resource) in the ListViewcontrol (left) and the selected
option from ListView (right) displayed via theTextView control

As mentioned earlier, another way to display items through ListView is to use Adapters,
which are the easiest and most flexible way of binding data to a control.
Adapters
Android provides a framework of adapters (also known as data adapters) that are used
to provide a data source for displaying content in the form of choices in selection widgets;
that is, they help create child elements for the selection widgets. The data source refers to the
content, including elements in arrays and data in database tables. The Adapters serve two
purposes. First, they provide the data source for a selection widget, and second, they convert
individual elements of data into specific Viewsto be displayed inside the selection widget. The
second purpose is important, as it casts the data to suit the selection widget environment,
overriding its default behavior, and also enables us to format the data in the available formats.
Android provides many basic Adapters such as ListAdapter,ArrayAdapter, and CursorAdapter. We
can also create our own Adapter. In this chapter, we use the ArrayAdapter for populating
selection widgets, as described in the next section.
Populating ListView Through the ArrayAdapter
The ArrayAdapter is one of the adapters provided by Android that provides data sources
(child elements) to selection widgets and also casts the data into specific view(s) to be
displayed inside the selection widgets. In this section, we learn to create an ArrayAdapter and
use it to populate theListView control. An ArrayAdapter can be created through string resource, as
well as through string arrays defined in Java code. We try the latter method in this section.
Create a new Android project called ListViewDemo1. Again, in this application, we use two
controls,ListView and TextView, where ListView displays the items assigned to
it through ArrayAdapterand the TextView displays the item that is selected by the user from
the ListView. Define the two controls by writing the code shown in Listing 5.4 into the layout
fileactivity_list_view_demo1.xml.

Listing 5.4. The Layout File activity_list_view_demo1.xml After Adding the ListView andTextView 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="wrap_content">
<ListView
android:id="@+id/fruits_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"/>
<TextView
android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Next, we need to write code into the Java activity file ListViewDemo1Activity.java to
serve the following purposes:
• Create an ArrayAdapter through a string array and assign it to the ListView for displaying items
• Display the item selected from the ListView in the TextView
The code written into the activity file ListViewDemo1Activity.java is shown in Listing 5.5.
Listing 5.5. Code Written into the Java Activity File ListViewDemo1Activity.java

package com.androidunleashed.listviewdemo1;

import android.app.Activity;
import android.os.Bundle;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;
import android.widget.ListView;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.view.View;

public class ListViewDemo1Activity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_demo1);
final String[] fruits={"Apple", "Mango", "Orange", "Grapes", "Banana"};
final TextView selectedOpt=(TextView)findViewById(R.id.selectedopt);
ListView fruitsList = (ListView)findViewById(R.id.fruits_list);
final ArrayAdapter<String> arrayAdpt= new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, fruits);
fruitsList.setAdapter(arrayAdpt);
fruitsList.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View v, int position,
long id){
selectedOpt.setText("You have selected "+fruits[position]);
}
});
}
}
An ArrayAdapter is the simplest of the adapters and acts as the data source for the
selection widgetsListView, GridView, and so on. An ArrayAdapter makes use of
the TextView control to represent the child Views in a View. In the code shown in Listing 5.5,
an ArrayAdapter is created through the following code:

ArrayAdapter<String> arrayadpt=new ArrayAdapter<String> (this,


android.R.layout.simple_list_item_1, fruits);

This constructor creates an ArrayAdapter called arrayAdpt that can display the elements
of the specified array, fruits, via the TextView control.
The ArrayAdapter constructor consists of the following:
• this (the current context)—As the Activity is an extension of the Context class, we use the
current instance as the context.
• android.R.layout.simple_list_item_1—Points to a TextView defined by the Android SDK
that will be used for displaying each item in the ListView. The elements of the array that is
specified next needs to be wrapped or cast in a view before being assigned to any selection
widget for display. So, theandroid.R.layout.simple_list_item_1 simply turns the strings defined in
the string array into a TextView for displaying them in a ListView.
• array—The data source—an array of strings for the ListView.
We can see that the ListView and TextView controls from the layout files are accessed
and mapped to the objects fruitsList and selectedOpt, respectively. The arrayAdpt
ArrayAdaptercontaining the elements of the fruits array in TextView form is assigned to
the ListView control for displaying choices to the user. The OnItemClickListener interface is
implemented via an anonymous class that implements a callback method, onItemClick(). The
reference of an anonymous class is passed to the fruitsList ListView to invoke the callback
methodonItemClick() when any of the items in ListView is clicked. In the onItemClick() method,
the item selected in the ListView is displayed via the TextView control selectedOpt. When we run
the application, the list of items is displayed via ListView, and the item selected from
the ListView is displayed via the TextView control, as shown in Figure 5.2.

Figure 5.2. Options displayed through Java code in the ListView control and the selected option
from ListView displayed through the TextView control

Now that we understand how to create a ListView through an Activity base class, let’s
createListView by extending the ListActivity class.

Creating ListView by Extending ListActivity


The ListActivity already contains a ListView, and we just need to populate it by calling
thesetListAdapter() method. If we just want to display a ListView and no other control in our
application, then there is no need of defining any View in the layout file main.xml,
as ListActivityautomatically constructs a full-screen list for us. Also there is no need of using
the onCreate()method for defining the content view of the activity for the simple reason
that ListActivity already contains a ListView control. If we want to display some other controls
along with ListView, we need to define the ListView and other desired controls in the layout
file main.xml.
Let’s create a new application to examine the creation of ListView by extending
the ListActivityclass. Name the new application ListViewDemo2. Because we want to
display ListView andTextView controls in our application, we need to use the layout
fileactivity_list_view_demo2.xml and write the code as shown in Listing 5.6.

Listing 5.6. The Layout File activity_list_view_demo2.xml After Adding ListView andTextView 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="wrap_content">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false" />
<TextView
android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Note that the ID assigned to the ListView control defined
in activity_list_view_demo2.xmlmust be @android:id/list; otherwise, ListActivity will not be able to
identify it. To populateListView and to display the item selected from it through
the TextView control, write the code intoListViewDemo2Activity.java as shown in Listing 5.7.

Listing 5.7. Code Written into the Java Activity File ListViewDemo2Activity.java

package com.androidunleashed.listviewdemo2;

import android.os.Bundle;
import android.app.ListActivity;
import android.widget.TextView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.view.View;

public class ListViewDemo2Activity extends ListActivity {


TextView selectedOpt;
String[] fruits={"Apple", "Mango", "Orange", "Grapes", "Banana"};

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_demo2);
selectedOpt=(TextView)findViewById(R.id.selectedopt);
ArrayAdapter<String> arrayAdpt = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_single_choice,fruits); #1
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); #2
setListAdapter(arrayAdpt);
}

@Override
public void onListItemClick(ListView parent, View v, int position, long id)
{
super.onListItemClick(parent, v, position, id);
selectedOpt.setText("You have selected "+fruits[position]);
}
}
We can see that an ArrayAdapter, arrayAdpt, is wrapping an array of strings.
The ListView is populated by assigning arrayAdpt to it via the setListAdapter() method.
TheonListItemClick() method is overridden to define the action that we want to take place when
any item in the ListView is clicked. The onListItemClick() method is executed when an item from
the ListView is selected. In the onListItemClick() method, the item selected by the user from
theListView is displayed through the TextView selected-Opt. Thesimple_list_item_single_choice term
in statement #1 and theListView.CHOICE_MODE_SINGLE in statement #2 allow us to select a
single item from theListView. On running the application, we see that items in
the ListView control appear in the form of a RadioButton control, allowing us to select only a
single item at a time (see Figure 5.3 (left). The chosen item is displayed through
the TextView control.

Figure 5.3. The ListView control with the choice mode set to single (left). and theListView control with the
choice mode set to multiple (right)

To enable users to select multiple items from the ListView,


replacesimple_list_item_single_choice with simple_list_item_multiple_choice in statement#1 and
change the choice mode in
statement #2 from ListView.CHOICE_MODE_SINGLE toListView.CHOICE_MODE_MULTIPLE. After
we make these two changes, the statements appear as shown here:

ArrayAdapter<String> arrayAdpt = new ArrayAdapter<String>(this,


android.R.layout.simple_list_item_multiple_choice,fruits);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

On running the application, we find that the items in the ListView control appear as CheckBoxes,
allowing us to select more than one item at a time, as shown in Figure 5.3 (right).

USING THE SPINNER CONTROL


The Spinner is akin to a drop-down list that displays a list of items, allowing the user to
select the desired item. After the user touches a Spinner or presses the center button of the D-
pad, a list of items is displayed, allowing the user to select an item from the list. To populate
the Spinner control, we use two methods: one via the string resource and the other via
the ArrayAdapter that acts as a data source.
Create a new Android project and name it as SpinnerApp. First, we populate the Spinner control
via the string resource and then by ArrayAdapter.

Populating a Spinner Through Resources


We define two resources, one to display a prompt in the Spinner control and the other
to display a list of choices. To display a prompt in the Spinner control, we define a string
resource. Open thestrings.xml file from the res/values folder and define a string resource in it. The
code is shown in Listing 5.8. The new code is shown in bold.

Listing 5.8. String Resource Defined in the strings.xml File

<resources>
<string name="app_name">SpinnerApp</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_spinner_app">SpinnerAppActivity</string>
<string name="choose_msg">Choose a fruit</string>
</resources>
We can see that a string resource called choose_msg is defined to represent the text Choose
Next, we need to define the resource for displaying options in the Spinner control. We
a fruit.
use astring-array to do this. To add a new xml file to the res/values folder, right-click on
theres/values folder in the Package Explorer window and select the New, Android XML Fileoption.
Call the file arrays (without the extension .xml) and then click the Finish button. The code
written in arrays.xml is shown in Listing 5.9.

Listing 5.9. String Array Defined in the arrays.xml File

<?xml version="1.0" encoding="utf-8"?>


<resources>
<string-array name="fruits">
<item>Apple</item>
<item>Mango</item>
<item>Orange</item>
<item>Grapes</item>
<item>Banana</item>
</string-array>
</resources>
We can see that a string-array called fruits is defined, consisting of five
elements, Apple,Mango, Orange, Grapes, and Banana. These array elements are used to display
options in theSpinner control. To display the Spinner control in the application, let’s define it in
the layout fileactivity_spinner_app.xml, as shown in Listing 5.10.

Listing 5.10. The activity_spinner_app.xml File with a Defined Spinner Control

<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">
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:prompt="@string/choose_msg"
android:entries="@array/fruits"/>
<TextView
android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
We can see that a Spinner control and a TextView control are defined.
The Spinner control displays a list of choices, and the TextView displays the choice selected by
the user from the Spinnercontrol. The prompt attribute is a string that appears at the top of
the Spinner control to guide the user. The choose_msg string resource, representing the
string Choose a fruit is set to appear as a Spinner control prompt. The entries attribute is used to
specify the data source to populate the Spinner control. We set the entries attribute to the string
array fruits that we just defined in arrays.xml.
We want the item selected from the Spinner control by the user to appear in the TextView. To
do so, write the code shown in Listing 5.11 into the Java activity file SpinnerAppActivity.java.

Listing 5.11. The Code Written into the Java Activity File SpinnerAppActivity.java

package com.androidunleashed.spinnerapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Spinner;
import android.widget.AdapterView;
import android.view.View;
import android.widget.AdapterView.OnItemSelectedListener;

public class SpinnerAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spinner_app);
final TextView selectedOpt=(TextView)findViewById(R.id.selectedopt);
Spinner spin=(Spinner)findViewById(R.id.spinner);
final String[] fruitsArray = getResources().getStringArray(R.array.fruits);
spin.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View v, int position,
long id) {
selectedOpt.setText("You have selected " +fruitsArray[position]);
}
public void onNothingSelected(AdapterView<?> parent) {
selectedOpt.setText("");
}
});
}
}
The Spinner control is captured from the layout file and is mapped to
the Spinner object spin. Similarly, the TextView is captured and mapped to
the TextView object selectedOpt. TheselectedOpt object is used to display the item selected from
the Spinner control. An event listener,setOnItemSelectedListener, is attached to the Spinner control.
When an item from theSpinner is selected, the onItemSelected() callback method that was
specified in the anonymous class passed to the Spinner’s setOnItemSelectedListener is called.
The onItemSelected()callback method retrieves the item that was selected in the Spinner and
displays it through theTextView. The item selected in the Spinner is retrieved from
the fruits array by specifying its index location—the position of the item selected from
the Spinner control.
The onNothingSelected() method is implemented to make the selectedOpt TextView blank;
that is, it removes any previous message being displayed through TextView control that was
selected earlier from the Spinner control.
When we run the application, the Spinner and TextView control appear as shown in Figure
5.4(left). After we select the drop-down arrow of the Spinner control, the items listed in the
spinner control are displayed as shown in Figure 5.4 (middle). After we select an item from
the Spinnercontrol, its name is displayed via the TextView control, as shown in Figure
5.4 (right).

Figure 5.4. Spinner control with a drop-down arrow (left), options displayed through an Arrays Resource in
the Spinner control (middle), and the option selected in the Spinner displayed through TextView (right)

Let’s now have a look at populating the Spinner control by using ArrayAdapter.

Populating a Spinner Through ArrayAdapter


Before populating the Spinner control with ArrayAdapter, we make it empty by removing
theandroid:entries="@array/fruits" attribute from the XML definition of the Spinner control in the
layout file main.xml. After we remove the entries attribute, the elements of the fruits string array
no longer are displayed in the Spinner control. After we remove the entries attribute from
theSpinner control, the layout file appears as shown in Listing 5.12.

Listing 5.12. The Layout File main.xml After Removing the entries Attribute from theSpinner Control

<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" >
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:prompt="@string/choose_msg"/>
<TextView
android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
There is no need to make any changes to strings.xml, the resource file, and we don’t
need thearrays.xml file either. To create an ArrayAdapter and to assign it to the Spinner control for
populating it, the code shown in Listing 5.13 is written into the Java activity
fileSpinnerAppActivity.java. The code shown in bold is the modified code; the remainder is the
same as Listing 5.11.

Listing 5.13. Code Written into SpinnerAppActivity.java

package com.androidunleashed.spinnerapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.view.View;
import android.widget.AdapterView.OnItemSelectedListener;

public class SpinnerAppActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spinner_app);
final TextView selectedOpt=(TextView)findViewById(R.id.selectedopt);
final String[] fruits={"Apple", "Mango", "Orange", "Grapes", "Banana"};
Spinner spin=(Spinner)findViewById(R.id.spinner);
ArrayAdapter<String> arrayAdpt=new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, fruits);
spin.setAdapter(arrayAdpt);
spin.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View v, int position,
long id) {
selectedOpt.setText("You have selected " +fruits[position]);
}
public void onNothingSelected(AdapterView<?> parent) {
selectedOpt.setText("");
}
});
}
}
An ArrayAdapter<String> object called arrayAdpt is created from the string array fruits, and
a standard simple_spinner_item view is used to display each bound element in the Spinnercontrol.
The arrayAdpt ArrayAdapter is assigned to the Spinner control for populating it. After we select an
item in the Spinner control, the onItemSelected() callback method is executed to display the
selected item through the TextView control. After we run the application,
the Spinnerand TextView control appears as shown in Figure 5.5 (left). After we select the drop-
down arrow of the Spinner control, the items listed in the Spinner control are displayed as
shown in Figure 5.5(middle). After we select an item from the Spinner control, its name is
displayed via the TextViewcontrol, as shown in Figure 5.5 (right).

Figure 5.5. Spinner control with a drop-down arrow (left), options displayed in theSpinner control via Java
code (middle), and the selected option displayed through the TextView (right)

AutoCompleteTextView
The AutoCompleteTextView control is an EditText control with auto-complete
functionality. As the user types, suggestions based on the entered characters appear. The user
can select any of the displayed suggestions to fill in the EditText control. To implement the
auto-complete facility, we create an ArrayAdapter and set it to display items or suggestions
from a data source, preferably an array, and wrap them in a View, called something
like simple_list_item_1 orsimple_dropdown_item_1. To understand
how AutoCompleteTextView works, let’s create a new application called AutoCompleteApp. Define
two controls, TextView andAutoCompleteTextView, in the layout
file activity_auto_complete_app.xml, as shown inListing 5.14.

Listing 5.14. The Layout File activity_auto_complete_app.xml After Defining


the TextViewand AutoCompleteTextView 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:text="Enter product name: "
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<AutoCompleteTextView android:id="@+id/product_names"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
To display a list of suggestions, we need to create an ArrayAdapter and associate it
withAutoCompleteTextView. To do so, the code shown in Listing 5.15 is written into
theAutoCompleteAppActivity.java Java activity file.

Listing 5.15. Code Written into the Java Activity File AutoCompleteAppActivity.java

package com.androidunleashed.autocompleteapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;

public class AutoCompleteAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
String[] products ={"Camera","Handi Cam","Cell phone","Laptop","Car"};
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auto_complete_app);
ArrayAdapter<String> arrayAdapt = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, products);
AutoCompleteTextView productNames = (AutoCompleteTextView)
findViewById(R.id.product_names);
productNames.setThreshold(1);
productNames.setAdapter(arrayAdapt);
}
}
We can see that an ArrayAdapter called arrayAdapt, is created and the array elements of
theproducts string array are set to display in it. The array elements are wrapped in
asimple_dropdown_item_1line View to show the suggestions. The arrayAdapt ArrayAdapteris then
associated with the AutoCompleteTextView, using the setAdapter() method.
ThesetThreshold() method is used to indicate the minimum number of characters that a user
must enter before the suggestions are displayed. We have set it to value 1 to display
suggestions when the user has typed even a single character.
Note
AutoCompleteTextView is a subclass of the EditText class.
On running the application, we get a TextView and an AutoCompleteTextView control on
startup. The TextView displays a message, Enter product name:, asking the user to type the
product name in the AutoCompleteTextView control. Figure 5.6 (left) displays the suggestions
after typing cin the AutoCompleteTextView, and Figure 5.6 (middle) displays available options
based on the characters cam typed in the AutoCompleteTextView control. Similarly, Figure
5.6 (right) displays the suggestions after typing l in the AutoCompleteTextView. As we type
more characters in theAutoCompleteTextView, suggestions become more specific.
Figure 5.6. The TextView and the AutoCompleteTextView displayed on application startup (left), possible
options displayed (middle) based on the characters that are typed, and available result after l is entered (right)

USING THE GRIDVIEW CONTROL


The GridView control is a ViewGroup used to display text and image data in the form of
a rectangular, scrollable grid. To display data in the grid, we first define a GridView control in
the XML layout, and then bind the data that we want to be displayed to it using
the ArrayAdapter.
Note
As the name suggests, ViewGroup is a view that contains other views known as child views.
The ViewGroup class is a base class for layout managers that are used to contain and arrange several
views. ListView, GridView, and other container controls are good examples of ViewGroups.
Let’s create a new Android project called GridViewApp. In this application, we display
certain strings arranged in a rectangular grid. When a user selects any of the strings, its name
is displayed. That is, we require two controls in this application: a GridView control for
arranging strings and a TextViewcontrol for displaying the string selected by the user. We
write the code shown in Listing 5.16 into theactivity_grid_view_app.xml layout file to define
a TextView and GridView control.

Listing 5.16. The Layout File activity_grid_view_app.xml After Defining the TextViewand GridView 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/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select a fruit " />
<GridView android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalSpacing="2dip"
android:horizontalSpacing="5dip"
android:numColumns="auto_fit"
android:columnWidth="130dip"
android:stretchMode="columnWidth"
android:gravity="center" />
</LinearLayout>
Let’s take a look at the different attributes used in GridView.

GridView Attributes
The number of rows displayed through GridView is dependent on the number of
elements supplied by the attached adapter. The size and number of columns is controlled
through the following attributes:
• android:numColumns—Defines the number of columns. If we supply a value, auto_fit,
Android computes the number of columns based on available space.
• android:verticalSpacing and android:horizontalSpacing—Define the amount of whitespace
between the items in the grid.
• android:columnWidth—Defines the width of each column.
• android:stretchMode—The attribute determines whether the column can stretch or expand
to take up the available space. The valid values for this attribute are
• none—Does not allow columns to stretch or expand
• columnWidth—Makes the columns take up all available space
• spacingWidth—Makes the whitespace between columns take up all available space
Listing 5.16 defines TextView and GridView controls with the IDs selectedopt and grid,
respectively. The GridView displays items or data in a rectangular grid, and TextView displays
the item selected by the user from the GridView. The horizontal and vertical spacing among
items in theGridView is set to 5dip and 2dip. The width of a column in GridView is set to 130dip.
The number of columns in the GridView is determined by the number of columns of 130dip that
can be accommodated in the available space. The columns are set to stretch to take up the
available space, if any. The GridView appears at the center of the LinearLayout container. To
display content in theGridView and to display the item selected from the GridView in TextView,
write the code shown inListing 5.17 into the Java activity file GridViewAppActivity.java.
Listing 5.17. Code Written into the Java Activity File GridViewAppActivity.java
package com.androidunleashed.gridviewapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.GridView;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.view.View;

public class GridViewAppActivity extends Activity implements


AdapterView.OnItemClickListener {
TextView selectedOpt;
String[] fruits={"Apple", "Mango", "Banana", "Grapes", "Orange", "Pineapple",
"Strawberry", "Papaya", "Guava", "Pomegranate", "Watermelon", "Chickoo", "Dates",
"Plum", "Cherry", "Kiwi"};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view_app);
selectedOpt=(TextView) findViewById(R.id.selectedopt);
GridView g=(GridView) findViewById(R.id.grid);
ArrayAdapter<String> arrayAdpt=new ArrayAdapter<String> (this,
android.R.layout.simple_list_item_1, fruits);
g.setAdapter(arrayAdpt);
g.setOnItemClickListener(this);
}
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
selectedOpt.setText("You have selected "+fruits[position]);
}
public void onNothingSelected(AdapterView<?> parent) {
selectedOpt.setText("");
}
}
We access the TextView with the selectedopt ID from the layout and map it to
the selectedOpt TextView object. We use the selectedOpt object to display the item selected by the
user in theGridView. An array of strings called fruits is created. It is the strings in this array that
we want to display in the GridView. We create an ArrayAdapter called arrayAdpt that makes the
elements in the string array fruits appear in the TextView form. The ArrayAdapter is set to
the GridViewvia the setAdapter() method to display its content via GridView.
By attaching ItemClickListener to the GridView, we are assured that when any item displayed
through GridView is clicked, the onItemClick() callback method is invoked. Through
theonItemClick() method, we display the item selected by the user in the GridView via
the TextView selectedOpt.
On running the application, we find that all items are displayed in the GridView, as
shown in Figure 5.7 (left). The item selected in the GridView is displayed through
the TextView control at the top. If we reduce the size of the column width in
the GridView definition, we can accommodate more columns. For example, modifying the
attribute shown in main.xml accommodates three columns in the GridView:

android:columnWidth="100dip"

Figure 5.7. Items displayed in two columns in GridView (left), and items displayed in three columns
in GridView (right)

After we set the column width to 100dip, three columns appear in the GridView control, as
shown inFigure 5.7 (right).
We have just seen the procedure for displaying text in a tabular format via
the GridView control. Let’s move one step further and try displaying images in
a GridView control.

Displaying Images in GridView


To display content in the GridView control, we use Adapters, which provide the content
to display to the controls. The content can be fetched from the sources such as arrays,
databases, or other data sources. In the previous example, we displayed text in
the GridView control through anArrayAdapter. In this section, we learn to create our own custom
adapter and subsequently use it to display images in the GridView control.
Let’s create a new application called GridImageApp. Assuming the image filenames that we
want to display through the GridView control are prod1.png, prod2.png, prod3.png, prod4.png,
andprod5.png, copy them into the four res/drawable folders. Our project in the Package
Explorerwindow appears as shown in Figure 5.8.

Figure 5.8. The Package Explorer window showing the images copied to theres/drawable folders
In this application, we want a message to be displayed showing the image number of
the picture displayed via the GridView control. Our application is therefore going to have two
controls: aTextView control for displaying the selected image number and a GridView control
for displaying images in a grid. After we add
the TextView and GridView controls,activity_grid_image_app.xml appears as shown in Listing 5.18.

Listing 5.18. The Layout File activity_grid_image_app.xml After Adding the TextView andGridView Controls

<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" >
<TextView android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="List of Products " />
<GridView android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalSpacing="2dip"
android:horizontalSpacing="2dip"
android:numColumns="auto_fit"
android:columnWidth="100dip"
android:stretchMode="columnWidth"
android:gravity="center" />
</LinearLayout>
We can see that the TextView and GridView controls are assigned the
IDs selectedopt and grid, respectively. The width of GridView columns is set to 100dip, and the
horizontal and vertical spacing between columns is set to 2dip.
To display images in the GridView control and also tell us which image is selected by
the user, write the code shown in Listing 5.19 into the activity file GridImageAppActivity.java.

Listing 5.19. Code Written into the Java Activity File GridImageAppActivity.java

package com.androidunleashed.gridimageapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.GridView;
import android.view.View;
import android.widget.ImageView;
import android.content.Context;
import android.widget.BaseAdapter;
import android.widget.AdapterView;
import android.widget.TextView;
import android.view.ViewGroup;

public class GridImageAppActivity extends Activity implements


AdapterView.OnItemClickListener {
TextView selectedOpt;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_image_app);
selectedOpt=(TextView) findViewById(R.id.selectedopt);
GridView g=(GridView) findViewById(R.id.grid);
g.setAdapter(new ImageAdapter(this));
g.setOnItemClickListener(this);
}

public void onItemClick(AdapterView<?> parent, View v, int position, long id) {


int p=position+1;
selectedOpt.setText("You have selected the image number "+p);
}

public class ImageAdapter extends BaseAdapter {


private Context contxt;
Integer[] images = {
R.drawable.prod1,
R.drawable.prod2,
R.drawable.prod3,
R.drawable.prod4,
R.drawable.prod5
};

public ImageAdapter(Context c) {
contxt = c;
}

public int getCount() {


return images.length;
}

public Object getItem(int position) {


return position;
}

public long getItemId(int position) {


return position;
}

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


ImageView imageView = new ImageView(contxt);
imageView.setImageResource(images[position]);
imageView.setLayoutParams(new GridView.LayoutParams(100, 120));
return imageView;
}
}
}
The TextView and GridView controls defined in activity_grid_image_app.xml with the
IDsselectedopt and grid, respectively, are fetched and mapped to the objects selectedOpt and g,
respectively. To create our custom adapter, ImageAdapter, we extend the BaseAdapter abstract
class that is provided by Android. To display the adapter’s content (images)
via GridView,ImageAdapter is set to the GridView object, g, via the setAdapter() method.
We instantiate our ImageAdapter, passing it the application context. An array
called images is defined containing the resource IDs of the images that we copied
into res/drawable folders. Theimages array acts as a data source, providing the images that we
want to display. BecauseImageAdapter is set to the GridView control, it can access the adapter
methods to display content. The adapter’s methods getCount(), getItem(), and getItemId() are used
to determine the number of images to be displayed and the unique identifier of the specified
image. The getView()method is used to retrieve the appropriate View, that is, the image at the
specified position. In thegetView() method, the member Context is used to create a
new ImageView. The ImageView is assigned an image from the images array that we defined
earlier. The height and width of the image are set by setting
the GridView.LayoutParams() method.
An AdapterView.OnItemClickListener event handler is attached to the GridView, so that
when any image displayed through GridView is clicked, the callback onItemClick() method is
invoked. In the onItemClick() method, we return the position of the clicked View; that is, the
image is returned. The position is zero based, so it is incremented by 1 before displaying the
image number via the selectedOpt TextView.
On running the application, we see that all images are displayed in GridView, as shown
in Figure 5.9(left). The image selected in the GridView is displayed through
the TextView control at the top, as shown in Figure 5.9 (right).

Figure 5.9. Images displayed in a GridView control (left), and the selected image number displayed via
a TextView (right)

CREATING AN IMAGE GALLERY USING


THE VIEWPAGER CONTROL
The ViewPager control (android.support.v4.view.ViewPager) helps in showing data, which
may be text, image, and so on, in the form of pages with the horizontal swiping behavior.
That is, the pages of data being displayed can be flipped left and right. To identify and to
keep track of the pages being displayed through ViewPager, a key object is associated with
each of them. The ViewPagerneeds a data adapter to define and load the data for each page.
The data adapter that is used to define the data for each page to be displayed through
the ViewPager control is the PagerAdapter (android.support.v4.view.PagerAdapter) class.
While implementing the PagerAdapter, we must override the following methods:
• instantiateItem(View container, int position)—Used for creating and instantiating the
page and adding it to the container. Using the LayoutInflater service, the method also inflates
the appropriate layout and adds it to the specified container.
Syntax:
public ObjectinstantiateItem(View container, int position)
• container—Represents the container in which the page has to be displayed.
• position—Represents the position of the page to be instantiated.
• destroyItem(View container, int position, Object object)—Used for removing the page
of the specified position from the container.
• isViewFromObject(View view, Object object)—Determines whether the specified page is
associated with a specific key object.
• getCount()—Defines the size of the paging range, that is, the count of the number of the
pages.
The position of the pages is zero based by default; that is, the first page to the left is in
position 0, the next page to the right is position 1, and so on. We can also set the initial
position of the pager through the setCurrentItem() method.
To listen to the change in state of the selected page, we need to define a class that
extendsSimpleOnPageChangeListener. When a page from the ViewPager is selected, the callback
method onPageSelected() is called.
Let’s apply all the knowledge gained so far in creating an application that displays a
scrollable image gallery, and when an image is selected from the gallery, the selected image
number is displayed. Let’s name this application ViewPagerApp. The first step is to copy the
images that we want to display through the gallery into the res/drawable folders of the
application. Assuming we have the files named prod1.png, prod2.png, prod3.png, prod4.png,
and prod5.png on our local disk drive, copy them into the res/drawable folders of our project.
Note
To support devices of different resolutions, the images of different resolution and size must be copied to
the res/drawable-xhdpi, res/drawable-hdpi, res/drawable-mdpi, andres/drawable-ldpi folders.
After copying the images, we define two controls, TextView and ViewPager, in the
layout fileactivity_view_pager_app.xml. The TextView control displays a message with the image
number selected from the image gallery. The ViewPager control displays the images in a
horizontally scrolling list. After we define
the TextView and ViewPager control,activity_view_pager_app.xml appears as shown in Listing 5.20.

Listing 5.20. The Layout File activity_view_pager_app.xml After Defining


the TextViewand ViewPager Controls

<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" >
<TextView android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Image Gallery "
android:gravity="center"
android:textStyle="bold" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="100dip"
android:layout_marginTop="25dip" />
</LinearLayout>
We can see that the TextView and ViewPager controls are assigned the
IDs selectedopt andviewpager, respectively. To make the image gallery appear at a distance
of 25dip from the top of the LinearLayout container, the android:layout_marginTop attribute is set
to 25dip. To constrain the height of the images being displayed to 100dip,
the android:layout_height is set to 100dip.
To display images in the ViewPager control and to display the image number selected by the
user, write the code shown in Listing 5.21 into the activity file ViewPagerAppActivity.java.

Listing 5.21. Code Written into the Java Activity File ViewPagerAppActivity.java

package com.androidunleashed.viewpagerapp;

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.PagerAdapter;
import android.widget.TextView;
import android.view.View;
import android.widget.ImageView;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;

public class ViewPagerAppActivity extends Activity {


public TextView selectedOpt;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_pager_app);
selectedOpt=(TextView) findViewById(R.id.selectedopt);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new ImageAdapter());
viewPager.setOnPageChangeListener(new PageListener());
}

public class ImageAdapter extends PagerAdapter {


Integer[] images = {
R.drawable.prod1,
R.drawable.prod2,
R.drawable.prod3,
R.drawable.prod4,
R.drawable.prod5
};

public Object instantiateItem(View container, int position) {


ImageView view = new ImageView(ViewPagerAppActivity.this);
view.setImageResource(images[position]);
((ViewPager) container).addView(view, 0);
return view;
}

@Override
public int getCount() {
return images.length;
}

@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
}

private class PageListener extends SimpleOnPageChangeListener{


public void onPageSelected(int position) {
selectedOpt.setText("You have selected the page number "+position);
}
}
}
The TextView and ViewPager controls defined in activity_view_pager_app.xml with the
IDsselectedopt and viewpager, respectively, are fetched and mapped to the respective
objectsselectedOpt and viewPager. We create our custom adapter, ImageAdapter, by extending
thePagerAdapter class. The ImageAdapter is set to the ViewPager object, viewPager, to display the
adapter’s content—the images via the ViewPager control. An array called images is defined,
containing the resource IDs of the images that we copied into the res/drawable folders.
The imagesarray acts as a source of images that we want to display.
The instantiateItem(), getCount(),destroyItem(), and isViewFromObject() methods define the pages,
determine the number of images to be displayed via ViewPager, and define the respective
unique identifier of the selected image.
A setOnPageChangeListener is attached to the ViewPager so that when any image is
selected from it, the onPageSelected() callback method is invoked, which in turn displays the
position of the clicked image through the TextView control. On running the application, we
find that all images are displayed through the ViewPager, as shown in Figure 5.10 (left). When
we select an image from the gallery, its position is displayed on the screen as seen in Figure
5.10 (middle). Figure 5.10 (right) shows the text message when the fourth image is selected
in the gallery.
Figure 5.10. Image displayed in the gallery control on application startup (left), hidden images displayed on
scrolling the gallery (middle), and the selected image number displayed via a TextView (right)

We have now created enough applications, but we don’t yet know how to fix coding
problems. Fortunately, Android supplies debugging tools, so let’s take a look at them.

USING THE DEBUGGING TOOL: 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 theWindow, 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 shows the DDMS tool window.
Figure 5.11. The DDMS tool window

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 theDevices 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
theDevice 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.
• 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
theDevices 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.

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 theFile Explorer tab. The Put
File on Devicedialog 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. To simulate an incoming phone call, select
the Voice option, provide the incoming phone number, and click the Call button, as shown
in Figure 5.15 (left). In the emulator, an incoming call appears, prompting the user to answer
the call in Figure 5.15 (right). The incoming call can be ended either by clicking
the End button in the emulator or by clicking the Hang Up button in the Emulator Control tab.

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).

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 theEmulator 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 inListing 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;
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

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

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 line19.
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
theVariables 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 toJava, 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).

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,
selectWindow, 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. Remember
that the variables (if any) used in the expression must exist in the application. After writing
an expression, press the Enter key to see the result, which is displayed in the Value column, as
shown in Figure 5.21(right).

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

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.
• 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 theSuspend 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 inListing 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

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. We can then examine the
variables and logging messages that might have thrown the exception. After we select the Java
Exception Breakpoint button, a dialog box showing all of the available exceptions is displayed,
as shown inFigure 5.25 (left).

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

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 oncaught 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 anException 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 theDebug 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 pressCtrl+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
theandroid.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;

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 inLogcat in green and red, respectively. To keep the tags consistent, it is better to
create static finalString 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 theLogCat 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, theapplication 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 LogCat filters (left), and filtered log messages displayed after selecting the
filter (right)

Let’s specify the filter name as checkfilter and Log Tag as CheckValue1, as we wish to see the log
messages related to this tag only. Specify the application
name ascom.androidunleashed.helloworldapp to focus only on the application’s logs. After we
selectOK, a filter called checkfilter is added and appears as a new tab in LogCat. After we select
thecheckfilter tab, only the log messages that satisfy the specified criteria are displayed, as
shown inFigure 5.28 (right).

Displaying and Fetching Information Using Dialogs


and Fragments
A dialog is 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?


We usually 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. We learned to work with the ProgressBar control in Chapter 4, “Utilizing
Resources and Media.”
• 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.
The rest of the code continues to execute in the background and also allows users to
simultaneously interact with the dialog. That means the dialogs in Android are modal in
nature. If the dialog is open, users can interact only with the options and controls in the dialog
until it is closed. While the user interacts with the dialog, the parent activity resumes its
normal execution for efficiency.
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 specialdialog 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 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
whenshowDialog() is called. Several dialog window types are available in the Android SDK,
such asAlertDialog, 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
withAlertDialog.
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
classAlertDialog.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 atitle, 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.
Note
The AlertDialog can display up to three buttons, and all three buttons cause the Alert-dialog to be
dismissed.
Let’s create an Android application to see how AlertDialog is displayed. Name the
projectAlertDialogApp. 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
fileactivity_alert_dialog_app.xml, which appears as shown in Listing 6.1.

Listing 6.1. 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
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. To do all this, the code into
theAlertDialogAppActivity.java Java activity file is as shown in Listing 6.2.

Listing 6.2. Code Written into 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,
theonClick() 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
thebuilder 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 This is an alert, as shown in Figure
6.1 (right).
Figure 6.1. 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,
theAlertDialog can also be used for getting input from the user. Let’s see how.

Getting Input via the Dialog Box


We modify our current Android project AlertDialogApp to get input from the user. We make
the following changes to the application:
• Dynamically create an EditText control and set it as part of the AlertDialog to prompt the user
for input.
• Add a TextView control to the layout file to display the data entered by the user in AlertDialog.
To make it more specific, our application asks the user to input a name through AlertDialog,
and when the user selects the OK button after entering a name, a welcome message is
displayed through theTextView control defined in the layout file. We also add a Cancel button
to the AlertDialog, allowing the user to cancel the operation, which terminates the dialog. We
don’t have to worry about defining the EditText control in the layout file, as it will be created
dynamically with Java code in the activity file. The only thing that we need to define
in main.xml is a TextView control that will be used for displaying a Welcome message on the
screen. The code shown in Listing 6.3 is added to the layout file for defining
the TextView control. Only the code in bold is newly added; the rest is the same as we saw
in Listing 6.1.

Listing 6.3. The Layout File activity_alert_dialog_app.xml After Adding the TextViewControl

<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
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/click_btn"
android:text="Click for Alert Dialog"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/response"/>
</LinearLayout>
We can see that the newly added code defines a response TextView control in the layout file.
Next we add code to the Java Activity file AlertDialogAppActivity.java to do the following tasks:
• Dynamically create an EditText control and set it as the content of the AlertDialog.
• Access the TextView control from the layout file main.xml and map it to a TextView object.
• Fetch the name entered by the user in the EditText control and assign it to the TextView object
for displaying a welcome message.
• Register an event listener for the Cancel button. Recall that the purpose of the Cancel button is
to cancel the operation and terminate the AlertDialog.
To perform all these tasks, the code shown in Listing 6.4 is added toAlertDialogAppActivity.java.
Only the code in bold is newly added; the rest is the same as we saw in Listing 6.2.
Listing 6.4. Code Written into 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.widget.EditText;
import android.widget.TextView;
import android.view.View;
import android.app.AlertDialog;
import android.content.DialogInterface;

public class AlertDialogAppActivity extends Activity implements OnClickListener {


TextView resp;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alert_dialog_app);
resp = (TextView)this.findViewById(R.id.response);
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("Enter your name ");
final EditText username = new EditText(this);
alertDialog.setView(username);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int buttonId) {
String str = username.getText().toString();
resp.setText("Welcome "+str+ "!");
return;
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int buttonId) {
return;
}
});
alertDialog.show();
}
}
We can see here that the TextView control from the layout file is mapped to
the TextView objectresp. The message set in the AlertDialog is Enter your name. The dynamically
createdEditText control username is set to appear as content in the AlertDialog, allowing users to
enter a name. When a user selects the OK button after entering a name, a Welcome message is
displayed, along with the entered name via the TextView object resp. No action is performed
when Cancel is clicked; we simply terminate the AlertDialog by returning back to the main
activity.
After running the application, we see a Button control with the caption Click for Alert
Dialog. When clicked, it displays an AlertDialog with the title Alert window that shows the
messageEnter your name. There is also an EditText control prompting the user to enter a name, as
shown in Figure 6.2 (left). After the user enters a name in EditText and click the OK button, a
welcome message is displayed via the TextView control, as shown in Figure 6.2 (right).

Figure 6.2. Getting input from the user via the AlertDialog (left), and the data entered by the user displayed
through TextView (right)

The next dialog we are going to discuss is DatePickerDialog, which is used to set the system
date.
DatePickerDialog
DatePickerDialog is used to see and modify the date. We can supply the day, month, and
year values to its constructor to initialize the date initially displayed through this dialog. The
constructor includes a callback listener to inform the current Context when the date has been
set or changed. To initialize the current date to the dialog, we use a Calendar instance. To
try DatePickerDialog, let’s create a new Android project and name it DatePickerApp. The
application contains a TextView and a Button control. When clicked, the Button control displays
the DatePickerDialog, and theTextView control displays the date set by the user.
To define the Button and TextView control, let’s write the code shown in Listing 6.5 into the
layout file activity_date_picker_app.xml.

Listing 6.5. The Layout File activity_date_picker_app.xml After Adding the TextView andButton 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/datevw"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button android:id="@+id/date_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Set the Date" />
</LinearLayout>
We can see that a TextView and a Button control with the IDs datevw and date_button,
respectively, are defined in the layout file. The caption Set the Date is set to display in
the Buttoncontrol.
To add action to the application, we need to write some Java code into the activity
fileDatePickerAppActivity.java. The code in the activity file does the following:
• Access the system’s current date through the Calendar instance.
• Display the current system date in the TextView control.
• Display the DatePickerDialog, initialized to display the current system date when
the Buttoncontrol is clicked.
• Access the date set by the user in the DatePickerDialog when its Set button is clicked and
display it through the TextView control.
To perform all the preceding tasks, the code shown in Listing 6.6 is written into the Java
activity fileDatePickerAppActivity.java.

Listing 6.6. Code Written into the Java Activity File DatePickerAppActivity.java

package com.androidunleashed.datepickerapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Button;
import java.util.Calendar;
import android.app.DatePickerDialog;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.DatePicker;

public class DatePickerAppActivity extends Activity {


private TextView dispDate;
private int yr, mon, dy;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_date_picker_app);
dispDate = (TextView) findViewById(R.id.datevw);
Button dateButton = (Button) findViewById(R.id.date_button);
final Calendar c = Calendar.getInstance();
yr = c.get(Calendar.YEAR);
mon = c.get(Calendar.MONTH);
dy = c.get(Calendar.DAY_OF_MONTH);
dispDate.setText("Current date is: "+(mon+1)+"-"+dy+"-"+yr);
dateButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new DatePickerDialog(DatePickerAppActivity.this, dateListener, yr,
mon, dy).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;
dispDate.setText("Current date is: "+(mon+1)+"-"+dy+"-"+yr);
}
};
}
When a user clicks a button, we want the DatePickerDialog to be invoked so a date can
be selected. A date_button Button is captured from the layout and mapped to
a Button object dateButton. A setOnClickListener event listener is associated with the Button so that
when it is clicked, the event handler, that is, the callback method, onClick(), is invoked. In
the onClick() method, a new instance of a DatePickerDialog is created using
the DatePickerDialog constructor and is displayed on the screen.
We want to initialize the DatePickerDialog to today’s date, so we use the Calendar class to
set theDatePickerDialog control to today’s date each time the dialog is shown. An instance
of Calendaris then created, initially set to the current date. The current year, month, and day are
fetched from theCalendar instance and passed to the DatePickerDialog constructor to initialize it
to display the current date. The constructor also includes a callback listener to inform the
current Context when the date is set or changed.
The DatePickerDialog provides a callback
listener, OnDateChangedListener orOnDateSetListener, that listens for when the user has finished
setting the date. This occurs when the user clicks the Set button in the DatePickerDialog.
The onDateSet() method is called when the date is set or changed, and we use it to display the
set date through the TextView. Note that the month value is zero-based. January is considered
month 0 and December month 11. To display the correct month, the mon variable, which
carries the month number of the selected month, is incremented by 1 before being displayed
through the TextView.
After running the application, we see a Button control with the caption Set the
Date (see Figure 6.3—top left). When clicked, it displays a DatePickerDialog showing today’s
date, as shown inFigure 6.3 (top right). We can change the day, month, and year as desired by
scrolling them in an up or down direction (see Figure 6.3—bottom left). After we set the date
in the DatePickerDialog, when the Done button is clicked, the currently set date is displayed via
the TextView control, as shown inFigure 6.3 (bottom right).
Figure 6.3. A TextView displaying the current date with a Button control (top left); the DatePicker dialog after
clicking the Button control (top right); changing the day, month, and year displayed through
the DatePicker dialog (bottom left); and displaying the date selected from the DatePicker dialog in
the TextView control (bottom right)

Let’s now see how system time can be accessed and set via TimePickerDialog.
TimePickerDialog
The TimePickerDialog allows us to set or select time through the built-in
Android TimePickerview. We can set the values of hour and minute with values of hour
ranging from 0 through 23 and minutes from 0 through 59. The dialog provides a callback
listener, OnTimeChangedListener orOnTimeSetListener, which tells us when a time is changed or
set by the user.
Again, we create a new Android project, called TimePickerApp, to see
how TimePickerDialogworks. In this application, we use two controls, TextView and a Button,
where the TextView control displays the current system time and the new time set by the user.
The Button control is used to invoke the TimePickerDialog; when the Button control is clicked,
the TimePickerDialogappears. To define TextView and Button, write the code shown in Listing
6.7 into the layout fileactivity_time_picker_app.xml.

Listing 6.7. The Layout File activity_time_picker_app.xml After Adding the TextView andButton 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/timevw"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button android:id="@+id/time_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Set the Time" />
</LinearLayout>
We can see here that the TextView and Button controls are defined with the
IDs timevw andtime_button, respectively. The caption on the Button control is Set the Time.
Next, we need to write code into the Java activity file TimePickerAppActivity.java to perform the
following tasks:
• Invoke the TimePickerDialog when the Button control is clicked.
• Display the current system time in the TextView control.
• Use the Calendar instance to initialize TimePickerDialog to display the current system time.
• Display the newly set time in the TextView control.
To perform these tasks, the code shown in Listing 6.8 is written into
theTimePickerAppActivity.java file.

Listing 6.8. Code Written into the Java Activity File TimePickerAppActivity.java

package com.androidunleashed.timepickerapp;

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.view.View.OnClickListener;
import android.view.View;
import android.widget.TimePicker;

public class TimePickerAppActivity extends Activity {


private TextView dispTime;
private int h, m;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time_picker_app);
dispTime = (TextView) findViewById(R.id.timevw);
Button timeButton = (Button) findViewById(R.id.time_button);
final Calendar c = Calendar.getInstance();
h = c.get(Calendar.HOUR_OF_DAY);
m = c.get(Calendar.MINUTE);
dispTime.setText("Current time is: "+h+":"+m);
timeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new TimePickerDialog(TimePickerAppActivity.this, timeListener,
h,m,true).show();
}
});
}

private TimePickerDialog.OnTimeSetListener timeListener = new


TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hour, int minute) {
h = hour;
m = minute;
dispTime.setText("Current time is: "+h+":"+m);
}
};
}
In this application, the timePickerDialog is displayed when the Button is selected.
The Buttonwith the text Set the Time and the ID time_button is captured from the layout and
mapped to aButton object timeButton. A setOnClickListener event listener is attached to the button
so that when it is clicked, the event handler callback method onClick() is invoked. In onClick(),
a new instance of a TimePickerDialog is created using the TimePickerDialog constructor and is
displayed on the screen.
To initialize the TimePickerDialog so it displays the current system time, we use
the Calendarclass. An instance of Calendar class is created that is initially set to be the current
system time. The current hour and minute values are fetched from the Calendar instance and
passed to theTimePickerDialog constructor to initialize it, which sets it to display current system
time. We also pass a Boolean value, true, to the constructor to indicate that we want to display
the 24-hour clock and not the 12-hour clock that displays AM/PM. The constructor also
includes a callback listener to inform the current Context (i.e., the current activity) when the
time is set or changed in theTimePickerDialog.
Note
If the Boolean value false is passed to the TimePickerDialog constructor, the hour appears in the 12-hour
format with an AM/PM button displayed.
The TimePickerDialog provides a callback
listener, OnTimeChangedListener orOnTimeSetListener, that listens for when the user is finished
setting the time by selecting the Donebutton. The onTimeSet() method is called when the time is
set or changed and we use it to display the selected time through the TextView.
After running the application, we see a Button control with the caption Set the
Time (see Figure 6.4—top left), which, when clicked, displays a TimePickerDialog showing the
current time, as shown in Figure 6.4 (top right). The current hour and minute are displayed,
and by scrolling them in an up or down direction, we can change them as desired (see Figure
6.4—bottom left). After we set the desired time in the TimePickerDialog and select
the Done button, the currently set time is displayed via the TextView control, as shown
in Figure 6.4 (bottom right).
Figure 6.4. The TextView displaying the current time with a Button control (top left), the TimePicker dialog
appears after selecting the Button control (top right), changing the hour and minutes displayed via
the TimePicker dialog (bottom left), and displaying the time selected from the TimePicker dialog in
the TextView control (bottom right)

How about combining the two controls DatePickerDialog and TimePickerDialog in one
application? This is covered in the next section.

SELECTING THE DATE AND TIME IN ONE APPLICATION


To see how 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, theTimePickerDialog is invoked.
So, let’s write the code shown in Listing 6.9 into the layout
fileactivity_date_time_picker_app.xml to define a TextView and two Button controls.

Listing 6.9. The Layout File activity_date_time_picker_app.xml After Adding


the TextViewand 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"
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
IDsdatetimevw, 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
theDateTimePickerAppActivity.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 andTimePickerDialog through the TextView control.
To perform these tasks, the code shown in Listing 6.10 is written
intoDateTimePickerAppActivity.java.

Listing 6.10. Code Written into 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);
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);
}
};
}
The respective listeners, OnDateSetListener and OnTimeSetListener, invoke their callback
methods, onDateSet() and onTimeSet(), when the Done button in
the DatePickerDialog orTimePickerDialog 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
in Figure 6.5(left). When the Set Date button is clicked, the DatePickerDialog showing the
system’s current date is displayed, as shown in Figure 6.5 (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, as shown in Figure
6.5 (right).

Figure 6.5. 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, as shown in Figure 6.6 (left). If we scroll in an up or down
direction, the hour and minute can be changed as desired, as shown in Figure 6.6 (middle).
After we set the desired time in the TimePickerDialog, the currently set date and time are
displayed via the TextView control, as shown in Figure 6.6 (right).

Figure 6.6. 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 DateTimePickerAppActivity.java file to appear as shown in Listing 6.11. Only the code in bold
is modified; the rest is the same as we saw inListing 6.10.

Listing 6.11. Code in 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();
}
});
}
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, as shown in Figure
6.7.

Figure 6.7. The formatted date and time

Let’s now move ahead to understand the concept called fragments.

FRAGMENTS
The size of the screen changes when a device is oriented from portrait to landscape
mode. In landscape mode, the screen becomes wider and shows empty space on the right. The
height becomes smaller and hides the controls on the bottom of the display. There is a
difference in screen sizes between the Android phone and Android tablet, as well. Android
tablets have a 7–10 inch display, whereas Android phones are in the range of 3–5 inches.
When developing an application, we need to arrange Views in such a way that the user
can view everything in both landscape and portrait mode. If we don’t organize the Views with
this in mind, problems arise if the user switches modes while running an application. One
solution to this problem is one we have already seen—designing an individual layout for each
device or screen mode. This solution is time consuming. Another solution is implementing
fragments in the application.

The Structure of a Fragment


A fragment is a combination of an activity and a layout and contains a set of views
that make up an independent and atomic user interface. For example, one or more fragments
can be embedded in the activity to fill up the blank space that appears on the right when
switching from portrait to landscape. Similarly, the fragments can be dynamically removed if
the screen size is unable to accommodate theViews. That is, the fragments make it possible for
us to manage the Views depending on the target device.
Let’s assume that we have two fragments, Fragment1 and Fragment2, each having its own set
ofViews. If the screen size is small, we can create two activities, each having a single
fragment, and display one activity at a time. If the device screen is able to accommodate
views of both Fragment1and Fragment2, these can be embedded into a single activity to fill up
the screen.
A fragment is like a subactivity with its own life cycle and view hierarchy. We can
add or remove fragments while the activity is running. Remember that the fragments exist
within the context of an activity, and so cannot be used without one.
Tip
Fragments are self-contained and can be used in multiple activities.
To create a fragment, we need to extend the Fragment class and implement several life
cycle callback methods, similar to an activity.

The Life Cycle of a Fragment


The life cycle of a fragments is affected by the activity’s life cycle in which it is
embedded. That is, when the activity is paused, all the fragments in it are paused. Similarly, if
an activity is destroyed, all of its fragments are destroyed, as well. The life cycle of a
fragment includes several callback methods, as listed here:
• onAttach()—Called when the fragment is attached to the activity.
• onCreate()—Called when creating the fragment. The method is used to initialize the items of
the fragment that we want to retain when the fragment is resumed after it is paused or
stopped. For example, a fragment can save the state into a Bundle object that the activity can
use in theonCreate() callback while re-creating the fragment.
• onCreateView()—Called to create the view for the fragment.
• onActivityCreated()—Called when the activity’s onCreate() method is returned.
• onStart()—Called when the fragment is visible to the user. This method is associated with
the activity’s onStart().
• onResume()—Called when the fragment is visible and is running. The method is associated
with the activity’s onResume().
• onPause()—Called when the fragment is visible but does not have focus. The method is
attached to the activity’s onPause().
• onStop()—Called when fragment is not visible. The method is associated with the
activity’sonStop().
• onDestroyView()—Called when the fragment is supposed to be saved or destroyed. The view
hierarchy is removed from the fragment.
• onDestroy()—Called when the fragment is no longer in use. No view hierarchy is associated
with the fragment, but the fragment is still attached to the activity.
• onDetach()—Called when the fragment is detached from the activity and resources allocated
to the fragment are released.
A fragment also has a bundle associated with it that serves as its initialization
arguments. Like an activity, a fragment can be saved and later automatically restored by the
system.
To understand the concept of fragments, let’s create an Android project
called FragmentsApp. In this application, we are going to create two
fragments: Fragment1 and Fragment2. Fragment1 contains a selection widget, ListView, that
displays a couple of fruits to choose from. Fragment2 contains aTextView control to display the
fruit selected from the ListView of Fragment1. The fragments use individual XML layout files to
define their Views, so for the two fragments, let’s add two XML files
called fragment1.xml and fragment2.xml to the res/layout folder.
To define a ListView control in the first fragment, the code shown in Listing 6.12 is
written into the XML file, fragment1.xml.

Listing 6.12. Code Written into the XML File fragment1.xml

<?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"
android:background="#0000FF" >
<ListView
android:id="@+id/fruits_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"/>
</LinearLayout>
We can see here that a ListView selection widget is defined with the ID fruits_list. For
distinguishing the two fragments, the background of this fragment is set to blue. To define
a TextViewcontrol for the second fragment, the code shown in Listing 6.13 is written into the
XML filefragment2.xml.

Listing 6.13. Code Written into the XML File fragment2.xml

<?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" >
<TextView
android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Please select a fruit" />
</LinearLayout>
We can see that a selectedopt TextView control is defined and is set to display Please select
a fruit.
Each fragment has a Java class that loads its UI from the XML file, so for the two
fragments, we need to add two Java classes to our application.
Add Fragment1Activity.java andFragment2Activity.java to
the com.androidunleashed.fragmentsapp package of the application. The code shown in Listing
6.14 is written into the Java class file of the first fragment,Fragment1Activity.java.

Listing 6.14. Code Written into the Java Class File Fragment1Activity.java

package com.androidunleashed.fragmentsapp;

import android.app.Fragment;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.View;
import android.view.LayoutInflater;
import android.widget.ListView;
import android.widget.ArrayAdapter;
import android.content.Context;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;

public class Fragment1Activity extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
Context c = getActivity().getApplicationContext();
View vw = inflater.inflate(R.layout.fragment1, container, false);
final String[] fruits={"Apple", "Mango", "Orange", "Grapes", "Banana"};
ListView fruitsList = (ListView) vw.findViewById(R.id.fruits_list);
ArrayAdapter<String> arrayAdpt= new ArrayAdapter<String>(c,
android.R.layout.simple_list_item_1, fruits);
fruitsList.setAdapter(arrayAdpt);
fruitsList.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View v, int position,
long id)
{
TextView selectedOpt = (TextView) getActivity().findViewById(R.
id.selectedopt);
selectedOpt.setText("You have selected "+((TextView) v).getText().
toString());
}
});
return vw;
}
}
We can see that the Java class for the fragment extends the Fragment base class. To
access and draw the UI for the fragment, the onCreateView() method is overridden. In
the onCreateView()method, a LayoutInflater object is used to inflate the UI—the ListView control
we defined in thefragment1.xml file. The ListView and TextView controls are accessed from the
layout files and mapped to the objects fruitsList and selectedOpt, respectively.
The arrayAdpt Array Adapter containing the elements of the array, fruits in TextView form, is
assigned to the ListView control for displaying choices to the user.
The OnItemClickListener interface is implemented via an anonymous class that implements a
callback method, onItemClick(). The reference to the anonymous class is passed to
the ListView, fruitsList, to invoke the callback methodonItemClick() when any item in
the ListView is clicked. In the onItemClick() method, the item selected in the ListView is
displayed via the TextView control selectedOpt.
Note
Besides the Fragment base class, a fragment can also extend a few other subclasses of theFragment class,
such as DialogFragment, ListFragment, and PreferenceFragment, as we see later in this chapter.
To load the UI of the second fragment from the XML file fragment2.xml, write the code shown
inListing 6.15 into the Java class file of the second fragment Fragment2-Activity.java.

Listing 6.15. Code Written into the Java Class File Fragment2Activity.java

package com.androidunleashed.fragmentsapp;

import android.app.Fragment;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.View;
import android.view.LayoutInflater;

public class Fragment2Activity extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
return inflater.inflate(R.layout.fragment2, container, false);
}
}
Like the Java class of the first fragment, this class also extends the Fragment base class.
TheonCreateView() method is overridden where a LayoutInflater object is used to inflate
theTextView control we defined in the fragment2.xml file.
To accommodate both the fragments in the application, the code shown in Listing 6.16 is
written into the layout file activity_fragments_app.xml.

Listing 6.16. The Layout File activity_fragments_app.xml After Adding the Two Fragments

<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="horizontal" >
<fragment
android:name="com.androidunleashed.fragmentsapp.Fragment1Activity"
android:id="@+id/fragment1"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<fragment
android:name="com.androidunleashed.fragmentsapp.Fragment2Activity"
android:id="@+id/fragment2"
android:layout_weight="0"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
Here we can see that the two fragments are added to the activity through
the <fragment> elements. The fragments are assigned the IDs fragment1 and fragment2,
respectively. The fragments are set to refer to their respective Java class through
the android:name attribute. The first fragment refers to its Java class file Fragment1Activity, which
was placed in thecom.androidunleashed.fragmentsapp package. The orientation of the
containerLinearLayout, was set to horizontal, so both the fragments appear beside each other. We
don’t have to write any code into FragmentsAppActivity.java. We can leave the default code
unchanged, as shown in Listing 6.17.

Listing 6.17. Code Written into the Java Activity File FragmentsAppActivity.java

package com.androidunleashed.fragmentsapp;

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

public class FragmentsAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragments_app);
}
}
After we run the application, the two UIs defined in Fragment1 and Fragment2 appear
side by side. The ListView of Fragment1 displays the list of items, and Fragment2 displays
the TextViewasking the user to Please select a fruit, as shown in Figure 6.8 (left). After a fruit has
been selected from the ListView, its name is displayed through the TextView, as shown
in Figure 6.8(right).
Figure 6.8. ListView and TextView controls displayed via two fragments (left), and the TextView of the second
fragment, showing the item selected from the ListView of the first fragment (right)

In the preceding example, we saw how two fragments were included in an activity.
But the main benefit of using fragments lies in the fact that it provides the freedom to add
fragments to the activity when a device is switched to landscape mode or when it has empty
space on the right. It’s also easier to remove fragments when the device switches to portrait
mode. So, let’s modify our application FragmentsAppin such a way that when the device is in
portrait mode, only one fragment is made visible, and when the device switches to landscape
mode, two fragments are made visible to fill up the empty space on the right.
To be more precise, we want only the ListView control to appear when the device is in
portrait mode. When an item is selected from the ListView, the TextView should appear on the
next screen in another activity. We also require that when the device is in landscape mode,
both controls, theListView and the TextView, should appear beside each other, as there will be
enough space on the right.
Traditionally, the layout file activity_fragments_app.xml contains the UI to display when
the device is in portrait mode. Because we want only Fragment1 to be visible when the device
is in portrait mode, let’s remove Fragment2 from the layout file. After we remove the Fragment2,
the layout file activity_fragments_app.xml appears as shown in Listing 6.18.

Listing 6.18. The Layout File activity_fragments_app.xml with a Single Fragment

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:name="com.androidunleashed.fragmentsapp.Fragment1Activity"
android:id="@+id/fragment1"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
We can see that Fragment1 with the ID fragment1 is added to the layout file, which
means only theListView control of Fragment1 is displayed when the device is in portrait mode.
Because we want the UI of Fragment1 and Fragment2 to appear when the device is in
landscape mode, create a folder called layout-land in the res folder and copy the XML
fileactivity_fragments_app.xml from the res/layout folder to the res/layout-land folder.
Note
If you recall from Chapter 3, “Laying Out Controls in Containers,” when a device switches to the
landscape mode, the layout file from the res/layout-land folder is used to displayViews on the screen. When
the device switches to portrait mode, the layout file from theres/layout folder is used for
displaying Views on the screen.
To the activity_fragments_app.xml file in res/layout-land folder, add the two
fragments,Fragment1 and Fragment2. After we add these two fragments, the file appears as
shown in Listing 6.19.

Listing 6.19. The Layout File activity_fragments_app.xml with Two Fragments

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:name="com.androidunleashed.fragmentsapp.Fragment1Activity"
android:id="@+id/fragment1"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<fragment
android:name="com.androidunleashed.fragmentsapp.Fragment2Activity"
android:id="@+id/fragment2"
android:layout_weight="0"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
We can see that Fragment1 and Fragment2 were added to the layout file.
Next, we need to modify the Java class of the Fragment1, Fragment1Activity to appear as
shown in Listing 6.20. Only the code in bold is newly added; the rest is the same as we saw
in Listing 6.14.

Listing 6.20. Code Written into the Java Class Fragment1Activity.java

package com.androidunleashed.fragmentsapp;

import android.app.Fragment;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.View;
import android.view.LayoutInflater;
import android.widget.ListView;
import android.widget.ArrayAdapter;
import android.content.Context;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;
import android.content.Intent;
import android.content.res.Configuration;

public class Fragment1Activity extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
Context c = getActivity().getApplicationContext();
View vw = inflater.inflate(R.layout.fragment1, container, false);
final String[] fruits={"Apple", "Mango", "Orange", "Grapes", "Banana"};
ListView fruitsList = (ListView) vw.findViewById(R.id.fruits_list);
ArrayAdapter<String> arrayAdpt= new ArrayAdapter<String>(c,
android.R.layout.simple_list_item_1, fruits);
fruitsList.setAdapter(arrayAdpt);
fruitsList.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View v, int position,
long id)
{
if (getResources().getConfiguration().orientation == Configuration.
ORIENTATION_LANDSCAPE){
TextView selectedOpt = (TextView) getActivity().findViewById(R.
id.selectedopt);
selectedOpt.setText("You have selected "+((TextView)
v).getText().toString());
} else {
Intent intent = new Intent(getActivity().getApplicationCon-
text(), ShowItemActivity.class);
intent.putExtra("item", ((TextView) v).getText().toString());
startActivity(intent);
}
}
});
return vw;
}
}
Take a look at the onItemClick() method in Listing 6.20 that’s called when any item in
theListView shown through Fragment1 is selected. In the method, we first check to see whether
the device is in landscape mode. We know that the fragment2 is available when the device is in
landscape mode. So, if the device is in landscape mode, the TextView UI control defined
in fragment2.xml is accessed and assigned to the TextView object selectedOpt. The item selected
from the ListViewis displayed through the TextView.
If the fragment2 is not available, it means that the device is in portrait mode. However,
we want to display the TextView of the item selected from the ListView in another screen.
Recall from Chapter 2, “Basic Widgets,” that to start an activity, we need to first create a
new Intent specifying the current application context and the class name of the activity that we
want to launch, and pass this Intent to the startActivity() method. Let’s specify the class name of
the new activity asShowItemActivity, and specify it while creating a new intent. In the new
activity screen, we want to display the item selected from the ListView, so we put the selected
item in the intent under the keyitem. In the ShowItemActivity, we retrieve the selected item using
this key.
Let’s add a Java class called ShowItemActivity.java and write the content as shown in Listing
6.21.

Listing 6.21. Code Written into the Activity File for the Second FragmentShowItemActivity.java

package com.androidunleashed.fragmentsapp;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.widget.TextView;

public class ShowItemActivity extends Activity{


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation == Configuration.
ORIENTATION_LANDSCAPE) {
finish();
return;
}
setContentView(R.layout.fragment2);
Bundle extras = getIntent().getExtras();
if (extras != null) {
String selectedItem = extras.getString("item");
TextView textView = (TextView) findViewById(R.id.selectedopt);
textView.setText("You have selected "+selectedItem);
}
}
}
Here we check to see whether the device is in landscape mode. If so, then we finish the
activity (terminate the screen), as it’s not required—the Views of both the fragments can be
accommodated in a single screen. If the device is in portrait mode, the getExtras() method is
called to see whether anything is passed to it. If any Bundle is passed to the intent, the value
stored in it under the item key is accessed. The TextView from fragment2.xml is accessed and
mapped to a TextView object,textView, and the value passed to the intent (the name of the item
selected from the ListView) is displayed via the TextView control.
Recall that only the components declared in the application’s manifest
file AndroidManifest.xmlare visible to Android. Hence, the newly added
activity ShowItemActivity.java must be declared in AndroidManifest.xml to make it visible to
Android and hence to start it. TheAndroidManifest.xml file is shown in Listing 6.22. The
statements in bold are added to register the newly created activity ShowItemActivity.java.
Listing 6.22. Code in the AndroidManifest.xml File

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidunleashed.FragmentsApp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".FragmentsAppActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ShowItemActivity" android:label="@string/app_name"
/>
</application>
</manifest>
After we run the application, if the device is in portrait mode, only the UI
of fragment1 is visible, as shown in Figure 6.9 (left). When an item from the ListView is
selected, the selected fruit name is displayed via TextView on the new screen or activity, as
shown in Figure 6.9 (right).

Figure 6.9. In portrait mode, only the UI of the first fragment, ListView, is displayed (left), and the item
selected from the ListView is displayed via another activity (right).

When the device is switched to landscape mode, the UI of both the


fragments, ListView andTextView, is visible side-by-side, as shown in Figure 6.10 (left). The
selected item from the ListViewis shown via the TextView on the same screen, as shown
in Figure 6.10 (right).
Figure 6.10. In Landscape mode, the UI of both fragments, ListView and TextView, is displayed (left); and the
item selected from the ListView is displayed via the TextViewof the second fragment (right).

CREATING FRAGMENTS WITH JAVA CODE


Until now, we have been defining fragments statically by using <fragment> elements in
the layout file of the application. Let’s now learn how to add fragments to the activity during
runtime. For creating, adding, and replacing fragments to an activity dynamically, we use
the FragmentManager.
FragmentManager
As the name suggests, the FragmentManager is used to manage fragments in an activity. It
provides the methods to access the fragments that are available in the activity. It also enables
us to perform theFragmentTransaction required to add, remove, and replace fragments. To access
theFragmentManager, the method used is getFragmentManager(), as shown here:

FragmentManager fragmentManager = getFragmentManager();

To perform fragment transactions, we use the instance of the FragmentTransaction as shown


here:

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

A new FragmentTransaction is created using the beginTransaction() method of theFragmentManager.


The following code shows how to add a fragment:

FragmentManager fragmentManager = getFragmentManager()


FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment1Activity fragment = new Fragment1Activity();
fragmentTransaction.add(R.id.fragment_container, fragment, "TAG1");
fragmentTransaction.commit();

Here the Fragment1Activity is the Java class of the fragment, which is also used to load
the UI of the fragment from its XML file. We assume that the fragment_container is the ID of
the container that exists in the layout file where we want to put our fragment.
Usually LinearLayout orFrameLayout is used as the fragment_container. The TAG1 refers to the
unique ID to identify and access the fragment. The commit() method is used to apply the
changes.
Note
To add fragments dynamically, a container View must exist in the layout in which the Viewsof the
fragment are displayed.
Before we add a fragment, it is a wise idea to check whether it already exists by modifying
the code as shown here:

FragmentManager fragmentManager = getFragmentManager()


FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if(null==fragmentManager.findFragmentByTag(TAG1)){
Fragment1Activity fragment = new Fragment1Activity();
fragmentTransaction.add(R.id.fragment_container, fragment, "TAG1");
}
fragmentTransaction.commit();

We can see that the findFragmentByTag() method of the FragmentManager checks to see
whether any fragment with the given tag exists. One more method that can be used to identify
a fragment is findFragmentById(). The findFragmentById() method is used to identify the fragment
that is added to the Activity layout. Otherwise, findFragmentByTag() is preferred.
TheFragment1Activity is a Java class meant for loading the Views defined in the fragment’s
layout file.
To replace the fragment or content being displayed in the fragment_container with the View from
another fragment, we use the replace() method of the FragmentTransaction as shown here:

fragmentTransact.replace(R.id.fragment_container, fragment2, "TAG2");

In this statement, the Views of fragment2 replace the content being displayed in
thefragment_container of the Activity layout. To remove a fragment, we identify it either
through thefindFragmentById() or findFragmentByTag() methods and then use the remove() method
ofFragmentTransaction. The following code identifies the fragment via
the findFragmentById()method and then removes it:

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();


Fragment fragment = fragmentManager.findFragmentById(R.id.fragment);
fragmentTransaction.remove(fragment);
fragmentTransaction.commit();

Here we assume that a fragment with the ID fragment exists in the Activity. To identify the
fragment through the findFragmentByTag() method, the statement can be replaced by the
following:

Fragment fragment = fragmentManager.findFragmentByTag(TAG1);

Communicating Between Fragments


We can also pass information among the fragments. The two methods provided by
the Fragment class to enable communication between fragments
are setArguments() and getArguments(). ThesetArguments() method stores a Bundle in the fragment,
whereas the getArguments() method retrieves the Bundle to fetch the passed information.
The following code passes information from fragment 1 to fragment 2. We assume that fragmentis
the ID of the fragment container that exists in the layout file where we want to
display fragment 2.
final Fragment2Activity frag2 = new Fragment2Activity(); #1
final Bundle args = new Bundle(); #2
String selectedItem="Text to send to fragment 2"; #3
if(null==fragmentManager.findFragmentByTag(FRAG2)){ #4
args.putString("item", selectedItem); #5
frag2.setArguments(args); #6
fragmentTransaction.replace(R.id.fragment, frag2); #7
String tag = null; #8
fragmentTransaction.addToBackStack(tag); #9
fragmentTransaction.commit();
}

Statement #1, Fragment2Activity, represents the Java class of the fragment 2. A Java class
instance called frag2 is created. Statement #2 creates a Bundle object called args, and a
string,selectedItem, is defined in #3 that we want to pass to fragment 2. Statement #4 checks to
see whether fragment 2 doesn’t already exist in the layout. The selectedItem variable is saved in
theBundle object args under the key item in #5. The Bundle object args is stored in fragment 2 in#6.
Through statement #7, fragment 2 replaces the View in the fragment container of the layout file.
The statements #8 and #9 are meant for navigating to the previous fragment as discussed next.

Navigating to Previous Fragments


The Activity stack keeps track of previous Activities. When we press the back button,
the Activities in the Activity stack pop up, making their Views visible. In other words, the
Activity stack enables us to navigate back to previous screens by using the back button.
The same concept is applicable to fragments as well. To add the FragmentTransaction to the back
stack, we need to call the addToBackStack() method of FragmentTransaction before calling
the commit() method.
In the code shown previously, fragment 2 replaces fragment 1, which was being
displayed in the fragment container of the layout file. fragment 1 is added to the back stack,
making its Viewsinvisible. Pressing the back button then reverses the
previous FragmentTransaction and returns the View of the earlier fragment, fragment 1.

Retrieving Content Passed Through Bundle


We can access the content passed to the fragment via the Bundle that was saved
through thesetArguments() method. The getArguments() method accesses the Bundle that may be
passed to the fragment. The following code accesses the Bundle object passed to the fragment.
It also accesses the content passed under the item key and assigns it to the String selectedItem:

String selectedItem="";
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
if (null == state) state = getArguments();
if (null != state){
selectedItem = state.getString("item");
}
}
Saving and Restoring the State of Fragments
Fragments can also save their state to be restored later, just like Activities. The
callback methods meant for this purpose are onSaveInstanceState() and onRestoreInstanceState().
The onSaveInstanceState() Callback
The onSaveInstanceState() callback is used for saving the status of the fragment into
a Bundleobject, which is then used while restoring the fragment. The following code saves the
status of the fragment. It saves the value of the selectedItem variable into the Bundle under
theselectedfruit key.

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("selectedfruit", selectedItem);
}

The onRestoreInstanceState() Callback


The onRestoreInstanceState() callback is for restoring the fragment to its earlier saved
state. It uses the content in the Bundle that was used in the onSaveInstanceState() for getting the
previously saved content of the fragment. The following code restores the fragment status. It
retrieves the value under the selectedfruit key from the Bundle that was saved while
callingonSaveInstanceState():

@Override
public void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
selectedItem = savedInstanceState.getString("selectedfruit");
}

To understand how fragments are created programmatically, we create an application


similar to ourFragmentsApp application showing a ListView and TextView in landscape mode and
only aListView in portrait mode. When an item from the ListView is selected, its name is
displayed through a TextView. Let’s create a new Android project called FragmentCodeApp. Add
two layout files, fragment1.xml and fragment2.xml, to the res/layout folder. The fragment1.xml file
contains the code to display a ListView control, and fragment2.xml contains code to display
aTextView control. The code in fragment1.xml is the same as that as shown in Listing 6.12.
Similarly, the code written into fragment2.xml is the same as that shown in Listing 6.13. Write
the code shown in Listing 6.23 into the main layout file of the
application,activity_fragment_code_app.xml.

Listing 6.23. Code in the Layout File activity_fragment_code_app.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/fragment1"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/fragment2"
android:layout_weight="0"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
We can see that two LinearLayout elements are added to the layout file instead of the
fragments. This is because we are adding fragments dynamically through code. The Views of
the desired fragments are displayed through these LinearLayout containers.
The LinearLayout elements are assigned the IDs fragment1 and fragment2, respectively, to identify
them in the Java code.
To load the Views of the two layout files defined in fragment1.xml and fragment2.xml, add two
Java class files
called Fragment1Activity.java and Fragment2Activity.java to thecom.androidunleashed.fragmentcodeapp p
ackage of the application. To load the Viewsdefined in fragment2.xml, the code that is written
into Fragment2Activity.java is the same as that shown in Listing 6.15.
To load the Views defined in fragment1.xml, write the code shown in Listing 6.24 into the Java
class file Fragment1Activity.java. Only the code shown in bold is new; the rest of the code is the
same as Listing 6.20.

Listing 6.24. Code Written into the Java Class File Fragment1Activity.java

package com.androidunleashed.fragmentcodeapp;

import android.view.View;
import android.view.LayoutInflater;
import android.app.Fragment;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.ArrayAdapter;
import android.content.Context;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;
import android.content.Intent;
import android.app.FragmentManager;

public class Fragment1Activity extends Fragment{


protected static final String FRAG2 = "2";
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
Context c = getActivity().getApplicationContext();
View vw = inflater.inflate(R.layout.fragment1, container, false);
final String[] fruits={"Apple", "Mango", "Orange", "Grapes", "Banana"};
ListView fruitsList = (ListView) vw.findViewById(R.id.fruits_list);
ArrayAdapter<String> arrayAdpt= new ArrayAdapter<String>(c,
android.R.layout.simple_list_item_1, fruits);
fruitsList.setAdapter(arrayAdpt);
final FragmentManager fragmentManager = getFragmentManager();
fruitsList.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View v, int position,
long id){
if(null!=fragmentManager.findFragmentByTag(FRAG2)){
TextView selectedOpt = (TextView) getActivity().findViewById(R.
id.selectedopt);
selectedOpt.setText("You have selected "+((TextView)
v).getText().toString());
} else {
Intent intent = new Intent(getActivity().getApplicationCon-
text(), ShowItemActivity.class);
intent.putExtra("item", ((TextView) v).getText().toString());
startActivity(intent);
}
}
});
return vw;
}
}
We want only the View of the first fragment, ListView, displayed in portrait mode, and
when an item from the ListView is selected, the name of the selected item is displayed on the
next screen. The new screen is created through a new activity. So, add a Java class file
called ShowItemActivity.java to the com.androidunleashed.fragmentcodeapp package of the
application. In theShowItemActivity.java file, write the code as shown in Listing 6.21. As said
earlier, to inform about the newly added activity file to the application, we need to write a
statement as shown in Listing 6.22 in the AndroidManifest.xml file. To the main activity file of
the applicationFragmentCodeAppActivity.java, write the code as shown in Listing 6.25.

Listing 6.25. Code Written into the Java Activity File FragmentCodeAppActivity.java

package com.androidunleashed.fragmentcodeapp;

import android.app.Activity;
import android.os.Bundle;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.res.Configuration;

public class FragmentCodeAppActivity extends Activity {


private static final String FRAG1 = "1";
private static final String FRAG2 = "2";

public void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_code_app);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction =fragmentManager.beginTransaction();
if (getResources().getConfiguration().orientation == Configuration.ORIENTA-
TION_LANDSCAPE)
{
fragmentTransaction.add(R.id.fragment1, new Fragment1Activity(), FRAG1);
fragmentTransaction.add(R.id.fragment2, new Fragment2Activity(), FRAG2);
}
else
{
if(null!=fragmentManager.findFragmentByTag(FRAG2))
fragmentTransaction.remove(fragmentManager.findFragmentByTag(FRAG2));
fragmentTransaction.add(R.id.fragment1, new Fragment1Activity(), FRAG1);
}
fragmentTransaction.commit();
}
}
After we run the application, the output of the application is the same as that shown earlier
in Figures 6.9 and 6.10.
Tip
Besides making a class extend a Fragment base class, the fragments are also created by making the class
extend certain subclasses of the Fragment base class. Such fragments are known as specialized fragments.

CREATING SPECIAL FRAGMENTS


After understanding the procedure to create simple fragments, we learn to create
specialized fragments such as list fragments, dialog fragments, and preference fragments. To
create these, we extend from the following subclasses of the Fragment base class:
• ListFragment
• DialogFragment
• PreferenceFragment

Creating a ListFragment
A ListFragment is a fragment that contains a built-in ListView that can be set to display
items from a specified data source. The data source can be an array or a cursor. To
understandListFragments, let’s create an application consisting of a ListView and a TextView.
TheListView displays some items to choose from. The item selected from the ListView is
displayed through a TextView. In this application, the ListView is displayed via a ListFragment,
and theTextView is displayed via a simple fragment. The item selected from the ListView in
theListFragment is displayed through the TextView in the simple fragment. Let’s name the new
Android project ListFragApp. We first create a fragment to hold the TextView control. So, let’s
add an XML file called fragment2.xml to the res/layout folder of our project. Listing 6.26 shows
how to define a TextView control in fragment2.xml.

Listing 6.26. Code in the XML File fragment2.xml

<?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" >
<TextView
android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Please select a fruit" />
</LinearLayout>
We can see that a TextView control with the ID selectedopt is defined in
a LinearLayoutcontainer. The initial text assigned to the TextView control is Please select a fruit.
ThisTextView control is assigned text through Java code to indicate the item selected from
the ListView.
To load the UI of the fragment from fragment2.xml, we need to create a Java class file. So, add
a Java class file called Fragment2Activity.java under thecom.androidunleashed.listfragapp package.
Write the code as shown in Listing 6.27 into the Java class file, Fragment2Activity.java.

Listing 6.27. Code Written into the Java Class File of the Second FragmentFragment2Activity

package com.androidunleashed.listfragapp;

import android.app.Fragment;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.View;
import android.view.LayoutInflater;

public class Fragment2Activity extends Fragment {


public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
return inflater.inflate(R.layout.fragment2, container, false);
}
}
We can see that the Java class extends the Fragment base class.
The onCreateView() method is overridden when a LayoutInflater object is used to inflate
the TextView control UI that we defined in the fragment2.xml file.
We use ListFragment to display the ListView control. As I said earlier,
the ListFragment already contains a ListView so we don’t need to define a UI for this fragment.
We can directly add a Java class file that extends the ListFragment class. In this Java class file,
we write code to define the items to be displayed through the ListView of the ListFragment and
also to display the item selected from the ListView through the TextView of the Fragment2. So,
add a Java class calledFragment1Activity.java to the project and write the code shown in Listing
6.28 into it.

Listing 6.28. Code Written into the Java Class for the First FragmentFragment1Activity.java

package com.androidunleashed.listfragapp;

import android.app.ListFragment;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;

public class Fragment1Activity extends ListFragment {


final String[] fruits={"Apple", "Mango", "Orange", "Grapes", "Banana"};

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayAdapter<String> arrayAdpt = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, fruits);
setListAdapter(arrayAdpt);
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
TextView selectedOpt = (TextView) getActivity().findViewById(R.
id.selectedopt);
selectedOpt.setText("You have selected "+((TextView) v).getText().
toString());
}
}
As expected, the Java class extends the ListFragment base class to create a ListFragment.
To display content through the ListView of the ListFragment, an array called fruits is defined and
fruit names are assigned to it. In the onCreate() method, an ArrayAdapter object calledarrayadpt is
defined to display the elements of the fruits array in the simple_list_item_1mode. When we use
the setListAdapter() method, the content in the ArrayAdapter object,arrayadpt, is assigned to
the ListView for display. As expected, the onListItemClick() method is invoked when any of the
fruits displayed through the ListView control is selected. In this method, we display the name
of the selected fruit through the TextView control that we defined infragment2.xml.
To accommodate both the fragments in the application, code is written
intoactivity_list_frag_app.xml as shown in Listing 6.29.

Listing 6.29. The activity_list_frag_app.xml Layout File After Adding Two Fragments

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:name="com.androidunleashed.listfragapp.Fragment1Activity"
android:id="@+id/fragment1"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<fragment
android:name="com.androidunleashed.listfragapp.Fragment2Activity"
android:id="@+id/fragment2"
android:layout_weight="0"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
We can see that the fragment1 and fragment2 fragments are added to the activity through
the<fragment> elements. The fragments are set to refer to their respective Java classes through
theandroid:name attribute. We don’t have to write any code into the Java activity file of the
applicationListFragAppActivity.java. We leave the default code in the activity file unchanged, as
shown inListing 6.30.

Listing 6.30. Default Code in the Java Activity File ListFragAppActivity.java

package com.androidunleashed.listfragapp;

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

public class ListFragAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_frag_app);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_list_frag_app, menu);
return true;
}
}
After running the application, we see the two fragments side-by-side, as shown
in Figure 6.11 (left). TheListView on the left side appears through the ListFragment. The content
in the ListView is displayed via the Java class file of the ListFragment, Fragment1Activity.java. The
item selected from the ListView is displayed through the TextView defined in Fragment2, as
shown inFigure 6.11 (right).

Figure 6.11. The ListView displayed via ListFragment (left), and the Item selected from
the ListView of ListFragment, displayed via the TextView of the second fragment (right)
Using a DialogFragment
In Android, dialogs are asynchronous. Synchronous dialogs are those in which the
activity suspends its execution until a dialog is dismissed. While the user is interacting with
the dialog, no further execution takes place. Asynchronous dialogs are those in which activity
continues its normal execution, and at the same time users can interact with the dialog. The
activity accesses user interaction with the dialog by implementing callback methods. The
dialogs in Android are modal in nature; while a dialog is open, users cannot access any other
part of the application. The benefit of calling dialogs asynchronously is that it not only
increases code efficiency, but also provides us with the capability to dismiss the dialog
through code.
We can display a DialogFragment by extending the DialogFragment base class, which in
turn is derived from the Fragment class. To demonstrate DialogFragment, let’s create a new
Android project called DialogFragApp. In this project, we use two fragments. One is used to
show aDialogFragment, and the other displays a TextView. The user’s interaction with
theDialogFragment is conveyed through the TextView control in the second fragment. The
selected button in the DialogFragment is displayed via the TextView control in the second
fragment.
Before beginning the creation of DisplayFragment, let’s first define the UI of the simple
fragment that consists of a TextView. To do so, add an XML file called fragment2.xml to
the res/layoutfolder. Write the code shown in Listing 6.31 into the fragment2.xml file.

Listing 6.31. Code Written into the XML File fragment2.xml

<?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" >
<TextView
android:id="@+id/selectedopt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select Open Dialog Button" />
</LinearLayout>
We can see that a TextView control is defined inside a LinearLayout container.
The TextView is assigned the selectedopt ID and is initialized to display the text Select Open Dialog
Button.This TextView is used to display the option selected by the user in the DialogFragment.
To load the UI of the fragment from fragment2.xml, a Java class file
calledFragment2Activity.java is added to the project. Write the code shown in Listing 6.32 into
the Java file Fragment2Activity.java.

Listing 6.32. Code Written into the Java Class for the Second FragmentFragment2Activity.java

package com.androidunleashed.dialogfragapp;

import android.app.Fragment;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.View;
import android.view.LayoutInflater;

public class Fragment2Activity extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
return inflater.inflate(R.layout.fragment2, container, false);
}
}
The Java class extends the Fragment base class. The onCreateView() method is
overridden when aLayoutInflater object is used to inflate the TextView control UI that we
defined in thefragment2.xml file.
To accommodate the fragment defined in fragment2.xml, we need to write code into the
layout fileactivity_dialog_frag_app.xml, as shown in Listing 6.33.

Listing 6.33. The Layout File activity_dialog_frag_app.xml After Adding a Fragment and a Button

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:name="com.androidunleashed.dialogfragapp.Fragment2Activity"
android:id="@+id/fragment2"
android:layout_weight="0"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<Button
android:id="@+id/dialog_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Open Dialog" />
</LinearLayout>
A Button control is defined because we want the DialogFragment to appear only when a
button is selected in the application. Both the Fragment and Button controls are nested inside
theLinearLayout container. The Fragment is assigned the ID fragment2 and is set to refer to its
Java class through the android:name attribute. The Button control is assigned the ID dialog_button,
and the caption as Open Dialog. fragment2 is meant to display a TextView to show the option
selected by the user in the DialogFragment.
Now it’s time to write code to show a DialogFragment. As stated earlier, to
show DialogFragment, a Java class needs to extend the DialogFragment class. Let’s add a Java
class calledFragment1Activity.java under the package com.androidunleashed.dialogfragapp. To display
a DialogFragment, write the code shown in Listing 6.34 into theFragment1Activity.java file.

Listing 6.34. Code Written into the Java Class File of the First FragmentFragment1Activity.java

package com.androidunleashed.dialogfragapp;
import android.app.DialogFragment;
import android.app.Fragment;
import android.os.Bundle;
import android.app.Dialog;
import android.app.AlertDialog;
import android.content.DialogInterface;

public class Fragment1Activity extends DialogFragment{


static Fragment1Activity newInstance(String title) {
Fragment1Activity fragment = new Fragment1Activity();
Bundle args = new Bundle();
args.putString("title", title);
fragment.setArguments(args);
return fragment;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String title = getArguments().getString("title");
Dialog diag = new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.ic_launcher)
.setTitle(title)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((DialogFragAppActivity) getActivity()).PositiveButton();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((DialogFragAppActivity) getActivity()).NegativeButton();
}
}).create();
return diag;
}
}
We can see that to create the DialogFragment, the Java class extends
the DialogFragment class. The newInstance() method is used to create a new instance of the
fragment. The title of theDialogFragment is passed to this method as an argument, which in turn
is stored in the Bundleobject and is associated with the fragment that is returned by this
method.
To create the view hierarchy of the DialogFragment, the onCreateDialog() method of
theDialogFragment class is overridden, and a Bundle object carrying the title of the fragment and
other information, if any, is passed to it. In the onCreateDialog() method, an alert dialog builder
is used to create a dialog object. In the beginning of this chapter, we learned that AlertDialog is
a dialog window that displays a message with optional buttons. In the onCreateDialog() method,
anAlertDialog with two buttons, OK and Cancel, is created, and the title that has to be displayed
in the fragment is obtained from the title argument saved in the Bundle object.
AnonClickListener() is associated with the two buttons OK and Cancel, which results in invoking
the respective onClick() method when the respective button is clicked. When OK is selected,
thePositiveButton() method from the activity is called. Similarly, when Cancel is selected,
theNegativeButton() method from the activity is called. The method returns the
createdAlertDialog.
In the Java activity file, we need to write code to invoke the DialogFragment. The code must be
written to take the necessary action when OK or Cancel is selected from the DialogFragment. The
code written into the Java activity file DialogFragAppActivity.java is shown in Listing 6.35.

Listing 6.35. Code Written into the Java Activity File DialogFragAppActivity.java

package com.androidunleashed.dialogfragapp;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.widget.TextView;

public class DialogFragAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog_frag_app);
Button dialogButton = (Button)findViewById(R.id.dialog_button);
dialogButton.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
Fragment1Activity dialogFragment = Fragment1Activity.
newInstance("Continue Processing?");
dialogFragment.show(getFragmentManager(), "Dialog Fragment Example");
}
});
}

public void PositiveButton() {


TextView selectedOpt = (TextView)findViewById(R.id.selectedopt);
selectedOpt.setText("You have selected OK button");
}

public void NegativeButton() {


TextView selectedOpt = (TextView) findViewById(R.id.selectedopt);
selectedOpt.setText("You have selected Cancel button");
}
}
We want the DialogFragment to appear when the Button is selected from the application.
So, we see that the dialogButton Button control is captured from the layout file and is mapped to
theButton object dialogButton. An OnClickListener is associated with the Button control, and
the onClick() callback method is called if the Button control is selected from the application. In
theonClick() method, the DialogFragment is created by creating a dialogFragment instance of
theFragment1Activity Java class file, and the title of the DialogFragment is passed to it asContinue
processing.
The DialogFragment is made visible by calling its show() method. The show() method
adds the fragment to the given FragmentManager. The code also defines the two
methods,PositiveButton() and NegativeButton(), which are invoked when OK and Cancel from
theDialogFragment are selected. In both the PositiveButton() and NegativeButton() methods,
the selectedOpt TextView control that we defined in fragment2.xml is accessed and mapped to
the TextView object selectedOpt. When OK is selected, a message, You have selected OK button,
appears in the TextView through the selectedOpt instance. Similarly, when Cancel from
the DialogFragment is selected, a message, You have selected Cancel button, appears in
the TextView of the second fragment.
After we run the application, a TextView and a Button control are displayed, as shown
in Figure 6.12(left). The TextView is displayed through fragment2.xml. The TextView displays the
initial textSelect the Open Dialog Button, directing the user to select the Open Dialog button. After
we click the Open Dialog button, a dialog fragment with the title Continue Processing opens,
showing two buttons, OK and Cancel, as shown in Figure 6.12 (middle). After we click
the OK button from the DialogFragment, a message, You have selected OK button, is shown through
theTextView control, as shown in Figure 6.12 (right).

Figure 6.12. The TextView and Button displayed on application startup (left), theDialogFragment appears after
clicking the button (middle), and the TextView showing that the DialogFragment OK button was clicked (right)

After we click the Open Dialog button again, the DialogFragment opens up once more.
This time, if we select Cancel from the DialogFragment, the TextView displays the message You
have selected Cancel button, as shown in Figure 6.13.

Figure 6.13. The TextView showing that the DialogFragment Cancel button was clicked

Using PreferenceFragment
PreferenceFragment is a fragment that enables users to configure and personalize an
application. The PreferenceFragment can contain several Preference Views that help in uniformly
setting application preferences with minimum effort. Table 6.1 shows the list of Preference
Views that can be displayed via a PreferenceFragment.

Table 6.1. Preference Views That Can Be Displayed in PreferenceFragments

To understand how application preferences are set, let’s create a new Android project
calledPreferenceFragApp. There are two ways of displaying Preference Views in
aPreferenceFragment: through an XML file and through code. We prefer the XML approach, so
we first add a folder called xml to the res folder. Inside the res/xml folder, we add an XML file
calledpreferences.xml. This file contains the Preference Views we want to display to the user to
configure the application. The options selected by the user in Preference Views persist in the
application. The code written into the preferences.xml file is shown in Listing 6.36.

Listing 6.36. Code Written into XML File preferences.xml

<?xml version="1.0" encoding="utf-8"?>


<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Category 1">
<CheckBoxPreference
android:title="Pizza"
android:defaultValue="false"
android:key="Pizzakey" />
<EditTextPreference android:key="Namekey"
android:title="Enter your name: "
android:dialogTitle="Enter your information">
</EditTextPreference>
</PreferenceCategory>
<PreferenceCategory android:title="Category 2">
<RingtonePreference android:showDefault="true"
android:key="Audio" android:title="Select sound"
android:ringtoneType="notification">
</RingtonePreference>
<ListPreference android:title="Fruits List "
android:key="fruits_list"
android:entries="@array/fruits"
android:entryValues="@array/fruitselected"
android:dialogTitle="Choose a fruit">
</ListPreference>
</PreferenceCategory>
<Preference
android:title="Submit"
android:key="submitPref" />
</PreferenceScreen>
We can see that the Preference Views are shown in two categories: Category 1 and Category
2. Category 1 includes two Preference Views: a CheckBoxPreference and anEditTextPreference. Category
2 includes the RingtonePreference and ListPreference. Every Preference View needs to have
an android:key value that is used to identify and access its value. The android:title attribute is
used to assign initial text to the Preference View, and theandroid:defaultValue attribute is used to
assign a default value to the Preference View.
The CheckBoxPreference displays a check box as its UI element, and it stores a value in
Boolean form—either true or false. The value true is stored when the check box
in CheckBoxPreferenceis selected, and false when the check box is not selected. The default
value false is assigned to theCheckBoxPreference using the android:defaultValue attribute.
The EditTextPreference is assigned the Namekey key, and the title Enter your name: appears
as the text of the Preference View. When the EditTextPreference is selected, a dialog titledEnter your
information is displayed, asking the user to enter information. When the user clicksOK, the
entered information is saved to the preference store.
The RingtonePreference opens a dialog box showing the list of ringtones, allowing the
user to select a default ringtone or silent mode. The key assigned to the RingtonePreference isAudio,
and the dialog box is assigned the title Select sound. The android:ringtoneTypeattribute helps in
determining the list of ringtones to be displayed. Valid values forandroid:ringtoneType attribute
are ringtone, notification, alarm, and all.
The ListPreference shows a dialog box listing a set of preferences in the form of radio
buttons, allowing the user to select one of them. The dialog box is titled Choose a fruit and is
assigned the key fruits_list. The android:entries attribute assigns a string array named fruits to
theListPreference to show the list of preferences. That is, the elements in the fruits array display
text for the radio buttons displayed via the ListPreference. The android:entryValues attribute
defines another array, fruitselected, to hold the values of the elements defined in the fruitsarray.
The android:entryValues attribute represents an array that stores the values corresponding to the
radio button selected by the user.
The <Preference> elements display a Submit button in the PreferenceFragment that users
click after selecting the desired preferences from Preference Views to either store the
preferences or perform another action. The Submit button is assigned the key submitPref, which
is used to identify it in the Java code.
Next, we need to define two arrays in the strings.xml resource file: one to display text
for the radio button in the ListPreference and the second to store the values of the corresponding
elements in the first array. After we define the two arrays, the strings.xml file appears as shown
in Listing 6.37.

Listing 6.37. The Strings Resource File strings.xml After Defining the Two Arrays

<resources>
<string name="app_name">PreferenceFragApp</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_preference_frag_app">PreferenceFragAppActivity</string>
<string-array name="fruits">
<item>Apple</item>
<item>Mango</item>
<item>Orange</item>
<item>Grapes</item>
<item>Banana</item>
</string-array>
<string-array name="fruitselected">
<item>You have selected Apple</item>
<item>You have selected Mango</item>
<item>You have selected Orange</item>
<item>You have selected Grapes</item>
<item>You have selected Banana</item>
</string-array>
</resources>
The elements in the fruits array are used to display text for the radio buttons shown in
theListPreference, and the elements in the fruitsselected array show the values that are returned if
the corresponding elements in the fruits array are selected.
To load the Preference Views defined in preferences.xml, a Java class file calledPrefActivity.java is
added to the project. Write the code shown in Listing 6.38 into the Java class
file PrefActivity.java.

Listing 6.38. Code Written into PreferenceFragment PrefActivity.java

package com.androidunleashed.preferencefragapp;

import android.os.Bundle;
import android.app.Activity;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;

public class PrefActivity extends Activity {


public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new
PrefsFragment()).commit();
}

public static class PrefsFragment extends PreferenceFragment {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
Preference submitPref = (Preference) findPreference("submitPref");
submitPref.setOnPreferenceClickListener(new OnPreferenceClickListener()
{
public boolean onPreferenceClick(Preference preference) {
getActivity().finish();
return true;
}
});
} }}
To create the PreferenceFragment, a Java class called PrefsFragment is defined that extends
thePreferenceFragment class. The addPreferencesFromResource() method is called to load
thePreference Views in the PreferenceFragment from the XML file preferences.xml. TheSubmit button
defined in the preferences.xml file through the <Preference> element is accessed and mapped to
the Preference object submitPref. An OnPreferenceClickListenerevent handler is added to
the submitPref object. Its callback method, onPreferenceClick(), is implemented, which executes
when the submitPref Button is clicked. In theonPreferenceClick() method, we finish by closing
the PreferenceFragment and returning toPreferenceFragActivity.java to take necessary action on the
selected preferences. Through the Java activity file PreferenceFragAppActivity.java, we display
the preferences selected by the user via TextView controls.
To display the options selected from the Preference Views shown in
the PreferenceFragment, we need to define four TextView controls in the layout
file activity_preference_frag.xml. After defining the
four TextView controls activity_preference_frag_app.xml appears as shown in Listing 6.39.

Listing 6.39. The Layout File activity_preference_frag_app.xml After Adding the FourTextView Controls

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/pizza"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/name"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/ringtone"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fruit"/>
</LinearLayout>
We can see that the four TextView controls are assigned the IDs pizza, name, ringtone,
andfruit. The TextView controls are vertically arranged inside the LinearLayout container.
Thepizza TextView is used to indicate whether the user has checked the check box in
theCheckBoxPreference. The name TextView is used to display the name entered by the user in
theEditTextPreference. The ringtone TextView is used to display the type of ring tone selected by
the user in the RingtonePreference. The fruit TextView is used to display the fruit selected by the
user in the ListPreference.
To display the PreferenceFragment and show the preferences selected by the user, we
need to write the code shown in Listing 6.40 into the main activity
file PreferenceFragAppActivity.java.
Listing 6.40. Code Written into the Main Activity File PreferenceFragAppActivity.java

package com.androidunleashed.preferencefragapp;
import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.preference.PreferenceManager;
import android.content.SharedPreferences;
import android.widget.TextView;

public class PreferenceFragAppActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preference_frag_app);
startActivity(new Intent(this, PrefActivity.class));
}

@Override
public void onResume() {
super.onResume();
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(this);
TextView pizza=(TextView)findViewById(R.id.pizza);
TextView name=(TextView)findViewById(R.id.name);
TextView ringtone=(TextView)findViewById(R.id.ringtone);
TextView fruit=(TextView)findViewById(R.id.fruit);
if(Boolean.valueOf(prefs.getBoolean("Pizzakey", false)))
pizza.setText("You have selected Pizza");
else
pizza.setText("");
ringtone.setText("The ringtone selected is "+prefs.getString("Audio",
"Silent"));
name.setText("The name entered is "+prefs.getString("Namekey",""));
String selectedFruit = prefs.getString("fruits_list", "Apple");
fruit.setText(selectedFruit);
}
}
To display the PreferenceFragment, its activity class, PrefActivity.class, is started. To show
the preferences selected by the user in the PreferenceFragment, the TextView controls defined in
the layout file main.xml are accessed and mapped to the TextView objects.
The pizza, name,ringtone, and fruit TextViews are mapped to
the TextView objects pizza, name, ringtone, and fruit, respectively.
To find the options selected in the Preference Views, a SharedPreferences object
called prefsis created. To read the value of CheckBoxPreference, we access the shared
preferences and call thegetBoolean() method, passing the key of the CheckBoxPreference to it.
When theCheckBoxPreference Pizzakey key is passed to the getBoolean() method of
theSharedPreference instance, it returns true or false, indicating whether the check box
inCheckBoxPreference is checked.
Thereafter, EditTextPreference is accessed by passing its Namekey key to
the getString()method of the SharedPreference instance. Similarly,
the RingtonePreference andListPreference are accessed by passing their keys, Audio and fruits_list, to
thegetString() method of the SharedPreference instance. The preferences selected by the user in
the Preference Views are displayed via TextView controls.
To make the newly added activity PrefActivity.java visible to Android, it is declared
inAndroidManifest.xml by adding the following statement in it:

<activity android:name=".PrefActivity" android:label="@string/app_name" />

After running the application, we see the Preference Views defined in Category
1 andCategory 2. The CheckBoxPreference check box is unchecked by default. When the check
box is selected, it is checked, as shown in Figure 6.14 (left). When the EditTextPreference with
the textEnter your name: is selected, a dialog box titled Enter your information pops up. We can
enter a name or cancel the operation by selecting Cancel. Let’s enter Troy as shown in Figure
6.14(middle), then click OK to go back to the PreferenceFragment. When Select sound is clicked
and which represents RingtonePreference, a dialog box prompting the user to select a ringtone
type is opened, as shown in Figure 6.14 (right).

Figure 6.14. A PreferenceFragment showing different Preference Views (left),


theEditTextPreference prompting for information (middle), and the RingtonePreferenceprompting to select a
ringtone type (right)

Let’s select a Default ringtone followed by clicking the OK button to return to


thePreferenceFragment. After we select the ListPreference represented by Fruits List, a dialog box
titled Choose a fruit opens up showing several fruits in the form of radio buttons, as shown
in Figure 6.15 (left). Let’s select Orange. On selecting a fruit, we automatically return to
thePreferenceFragment. Finally, we click the Submit button at the bottom of
thePreferenceFragment to close the fragment and display the selected preferences. All the
selected preferences are shown through the TextView controls, as shown in Figure 6.15 (right).
Figure 6.15. The ListPreference showing selectable fruits in the form of radio buttons (left) and all the selected
preferences displayed via TextView controls (right)

You might also like