Mad PDF
Mad PDF
Mad PDF
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.
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.
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
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).
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:
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:
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:
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
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.
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.
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.
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
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.
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.
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
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 (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.
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:
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.
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 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.
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).
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.
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
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.
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;
@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.
<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.
12
Figure: Illustration of how ViewGroup objects form branches in the layout and contain other View objects.
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
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.
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
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
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
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
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
(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
(ViewGroup) findViewById(R.id.toast_layout_root));
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.
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:
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"/>
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"
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"
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);
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"
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);
android:id="@+id/simpleEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Password"
android:id="@+id/simpleEditText"
23
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
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"
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"
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:padding="15dp"
android:textColorHint="#fff"
android:textStyle="bold|italic"
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);
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;
Button submit;
@Override
30
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
submit.setOnClickListener(new View.OnClickListener() {
@Override
if (name.getText().toString().isEmpty() || password.getText().toString().isEmpty() ||
email.getText().toString().isEmpty() || date.getText().toString().isEmpty()
|| contact.getText().toString().isEmpty()) {
} else {
+ " \n" + "E-Mail - " + email.getText().toString() + " \n" + "Date - " + date.getText().toString()
});
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.
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: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;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
displayText.setOnClickListener(new View.OnClickListener() {
@Override
{
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.
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.
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.
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"
37
Setting Current State Of CheckBox In Java Class:
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"
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"
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()*/
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:textColor="#f00"
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:textColor="#00f"
android:checked="false"
40
android:textSize="20sp"/><!--set Text Size of text in CheckBox-->
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:textColor="#fff"
android:textSize="20sp"
android:textStyle="bold|italic"
android:checked="true"
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:textColor="#44f"
android:textSize="20sp"
android:textStyle="bold|italic"
android:checked="false"
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: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>
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;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initiate views
android.setOnClickListener(this);
python.setOnClickListener(this);
php.setOnClickListener(this);
unity3D.setOnClickListener(this);
@Override
switch (view.getId()) {
case R.id.androidCheckBox:
if (android.isChecked())
break;
case R.id.javaCheckBox:
if (java.isChecked())
break;
case R.id.phpCheckBox:
if (php.isChecked())
break;
case R.id.pythonCheckBox:
if (python.isChecked())
break;
48
case R.id.unityCheckBox:
if (unity3D.isChecked())
break;
<string name="app_name">CheckBoxExample</string>
<string name="action_settings">Settings</string>
<string name="android">Android</string>
<string name="java">Java</string>
<string name="php">PHP</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.
Boolean RadioButtonState = simpleRadioButton.isChecked(); // check current state of a radio button (true or false).
Table Of Contents :
Now let’s we discuss important attributes that helps us to create a beautiful radio button in xml file (layout).
<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.
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"
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"
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"
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:
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"
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"
10. drawableBottom, drawableTop, drawableLeft And drawableRight: These attribute draw the drawable to the
below of the text of 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-->
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
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:
▶ 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.
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.
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.
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.
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.
<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>
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.
▶ 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.
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:
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.
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
The attributes to control the position of a control in relation to other controls are
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_alignLeft—The left side of the control is set to align with the left
side of the referenced control.
▶ android:paddingTop—Defines the spacing between the content and the top 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:
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.
import android.app.Activity;
import android.os.Bundle;
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"
<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" />
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
<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.
▶ 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.
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
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;
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.
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 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.
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:
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.
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
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
import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
import android.view.View.OnClickListener;
import android.view.View;
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.
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:
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:
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:
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.
<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.
<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.
<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;
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
<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:
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:
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.
<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;
<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:
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.
<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.
package com.androidunleashed.valuesresourcesapp;
import android.app.Activity;
import android.os.Bundle;
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.
<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" />
<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.
<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.
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>
<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;
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.
<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.
<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;
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.
We have learned to use values resources. The next resource, drawable, is helpful in
displaying images in an Android application.
@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.
<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"
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.
package com.androidunleashed.dispimageapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
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.
<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.
<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.
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;
@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.
android:gravity="center"
android:layout_gravity="center"
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.
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;
@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.
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.
Figure 4.13. The Package Explorer window, showing the images dropped in theres/drawable folders
<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.
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;
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.
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;
Figure 4.15. (left) Two fixed images are displayed, and (right) scrolling images are displayed.
<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.
Figure 4.16. The newly added raw folder showing the audio, song1.mp3, which was added to it
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.
package com.androidunleashed.playaudioapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.media.MediaPlayer;
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.
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;
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.
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.
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;
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.
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.
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;
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.
<ProgressBar android:id="@+id/progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal" />
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);
progressBar.setProgress(60);
<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.
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;
@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();
}
}
});
}
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.
<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.
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;
}
}
}
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.
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.
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;
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;
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.
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;
@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)
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).
<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.
<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;
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.
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.
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;
@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.
<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;
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;
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.
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;
@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 ImageAdapter(Context c) {
contxt = c;
}
Figure 5.9. Images displayed in a GridView control (left), and the selected image number displayed via
a TextView (right)
<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;
@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());
}
@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);
}
}
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.
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)
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)
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.
package com.androidunleashed.helloworldapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.util.Log;
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.
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.
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.
package com.androidunleashed.helloworldapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.util.Log;
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)
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;
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:
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).
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.
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;
@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.
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;
@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;
@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();
}
});
}
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;
@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();
}
});
}
How about combining the two controls DatePickerDialog and TimePickerDialog in one
application? This is covered in the next section.
<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;
@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();
}
});
}
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.
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;
@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()));
}
};
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.
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;
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;
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;
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.
<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.
<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.
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;
@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;
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).
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:
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:
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:
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:
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.
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);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
selectedItem = savedInstanceState.getString("selectedfruit");
}
<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;
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;
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.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;
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;
@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.
package com.androidunleashed.listfragapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
@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.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;
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;
@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;
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.
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.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.
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;
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;
@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:
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).