Chapter Four:
Graphical User Interface
(GUI)
By: Gemmachis Teshite
Software Engineering Department
CCI
Contents
▪ Introduction
▪ Preparing containers and components
▪ Management of component layout
▪ Event handling
Introduction
All android applications, called apps, are built on Android UI
framework.
App interface is the first thing a user sees and interacts with.
From the user perspective, this framework keeps the overall
experience consistent for every app installed in our smartphone or
tablets.
At the same time, from the developer perspective, this framework
provides some basic blocks that can be used to build complex and
consistent user interface (API).
Cont’d…
Android UI interface is divided in three different areas:
Home screen
All apps screen
Recent screen
The home screen is the “landing” area when we power our phone
on. This interface is highly customizable and themed.
Using widgets, we can create and personalize our “home” screen.
All apps is the interface where the app installed are displayed, while
recent screens are the list of last used apps.
Android App Structure and UI patterns
Android apps are very different from each other because they try to
address different user needs.
There are simple apps with a very simple UI that has just only one
view and there are other apps much more complex with a very
structured navigation and multiple views.
In general, we can say an Android app is made by a top-level view
and detail/low-level view.
Cont’d…
One of the biggest efforts made by Google was to define a well-
defined set of rules that helps developers to create appealing user
interfaces.
At the same time, these rules help users to navigate through every
app in the same way. We call this UI consistency.
Android, moreover, guarantees to the developers the required
flexibility to customize the app look and feel and make it unique.
These rules are known as UI patterns.
Patterns are proven solution approaches to well known problems.
Thus, having a well-defined UI pattern catalog and knowing when
and where apply them, we can create appealing apps that are not
only full of interesting features, but they are enjoyable by users and
easy to use.
Top Level View
The top-level view is the “landing” area of our app, so we must reserve to
it a special attention, because this is the first thing a user sees of our app.
There are some specific patterns that can be applied when designing this
view depending on the type of information we want to show:
Fixed tabs
Spinner
Scroll View
Navigation drawer
Recycler View and etc.……
We must choose one of them carefully depending on the nature of our
app.
Cont’d…
We can use fixed tabs when we want to give to the user an overview
of the different views present in our app, so that a user can switch
easily between them to show different type of information.
A typical example is a app that shows tech news: in this case we
could use different tabs to group news like (‘Android', iOS, ‘Games’
and so on).
Spinner is used when we want to move directly to a specific view,
this is the case of a calendar app when we can use spinner to go
directly to a specific month.
Cont’d…
The navigation drawer is one of the newest patterns introduced by
Google.
This is a sliding menu, usually at the left side of the smartphone
screen, that can be opened and closed by the user.
This pattern can be used when we have a multiple top-level view
and we want to give to the user a fast access to one of them, or we
want to give to the user the freedom to move to one low level view
directly.
This pattern replaces, somehow, an old pattern called dashboard
widely used in the past.
This pattern is simple a view where there are some big buttons/icons
to access to specific views/app features.
Detail View
The detail view is a low-level view where a user can interact with
data directly.
It is used to show data and edit them.
In this kind of view the layout plays an important role to make data
well organized and structured.
At this level, we can implement an efficient navigation to improve
usability of our app.
In fact, we can use swipe view pattern so that user can move
between different detail views.
Depending on the type of component we use to show detail
information to the user, we can implement some low-level patterns
that simplify the user interaction with our app.
Action Bar
The action bar is relatively new in Android and was introduced in
Android 3.0 (API level 11).
It is a well-known pattern that plays an important role.
An action bar is a piece of the screen, usually at the top, that is
persistent across multiple views.
It provides some key functions:
App branding: icon area
Title area
Key action area
Menu area
▪ Introduction
▪ Preparing containers and components
▪ Management of component layout
▪ Event handling
Standard Components
How do we build a user interface? Android gives some key
components that can be used to create user interface that follows the
pattern we talked about before.
All the Android user interface are built using these key components:
View: It is the base class for all visual components (control
and widgets). All the controls present in an android app are
derived from this class. A View is an object that draws
something on a smartphone screen and enables a user to
interact with it.
ViewGroup: A ViewGroup can contain one or more Views
and defines how these Views are placed in the user interface
(these are used along with Android Layout managers.)
Cont’d…
Fragments: Introduced from API level 11, this component
encapsulates a single piece of UI interface.
They are very useful when we have to create and optimize our app
user interface for multiple devices or multiple screen size.
Activities Usually an Android app consists of several activities that
exchange data and information.
An Activity takes care of creating the user interface.
Cont’d…
Moreover, Android provides several standard UI controls, Layout
managers and widgets that we can use without much effort and
with which we can create apps fast and simply.
Furthermore, we can extend them and create a custom control with a
custom layout and behaviour.
Using these four components and following standard UI patterns we
can create amazing apps that are “easy-to-use”.
Cont’d…
Android provides some standard UI components that can be grouped
in:
Tabs
Spinners
Pickers
Lists
Buttons
Dialogs
Grid lists
TextFields
Cont’d…
The figure below shows some Android custom components:
Layout
If we analyze in more detail an Android user interface, we can
notice that it has a hierarchical structure where at the root there’s a
ViewGroup.
A ViewGroup behaves like an invisible container where single
views are placed following some rules.
We can combine ViewGroup with ViewGroup to have more control
on how views are located.
We have to remember that more complex is the user interface more
time the system requires to render it.
Therefore, for better performance we should create simple UIs.
Additionally, a clean interface helps user to have a better experience
when using our app.
Cont‘d..
A layout defines the structure for a user interface in your app, such
as in an activity.
All elements in the layout are built using a hierarchy of View and
ViewGroup objects.
A View usually draws something the user can see and interact with.
Whereas a ViewGroup is an invisible container that defines the
layout structure for View and other ViewGroup objects.
The View objects are usually called "widgets" and can be one of
many subclasses, such as Button or TextView.
The ViewGroup objects are usually called "layouts" can be one of
many types that provide a different layout structure, such as
LinearLayout or ConstraintLayout .
Cont’d…
A typical UI structure is shown below:
You can declare a layout in two ways:
Cont’d…
Declare UI elements in XML. Android provides a
straightforward XML vocabulary that corresponds to the View
classes and subclasses, such as those for widgets and layouts.
You can also use Android Studio's Layout Editor to build your
XML layout using a drag-and-drop interface.
Instantiate layout elements at runtime. Your app can create
View and ViewGroup objects (and manipulate their properties)
programmatically.
Declaring your UI in XML allows you to separate the
presentation of your app from the code that controls its
behavior.
Using XML files also makes it easy to provide different layouts
for different screen sizes and orientations
Cont’d…
Layout is the architecture for the user interface in an Activity
Defines the layout structure and holds all the elements that appear to
the user
It express the view hierarchy
Each element in XML is either a View or ViewGroup object
View objects are leaves in the tree
ViewGroup objects are branches in the tree
The name of an XML element is respective to the Java class that it
represents
Cont’d…
If we create a simple android app, using our IDE, we can verify the
UI structure:
Cont’d…
From the example above, we can notice that at the top of the
hierarchy there is a ViewGroup (called RelativeLayout) and then
there are a list of view child (controls and widgets).
When we want to create an UI in Android we have to create some
files in XML format.
Android is very powerful from this point of view because we can
“describe” our UI interface just in XML format.
The OS will then convert it in a real code lines when we compile our
app and create the apk.
Android XML
XML stands for Extensible Markup Language.
XML is a markup language much like HTML used to describe
data.
XML tags are not predefined in XML.
We must define our own Tags.
Xml as itself is well readable both by human and machine. Also, it is
scalable and simple to develop.
In Android we use xml for designing our layouts because xml is
lightweight language, so it doesn’t make our layout heavy.
Advantage to declaring your UI in XML
It better separate the presentation of your application from
the code that controls its behavior
can modify or adapt it without having to modify your
source code and recompile
create XML layouts for different screen orientations
create XML layouts for different device screen sizes
create XML layouts for different languages
makes it easier to visualize the structure of your UI
Easier to debug problems
<?xml version"=1.0 "encoding"=utf-8"?>
<LinearLayout xmlns:android"=… "
android:layout_width"=fill_parent"
android:layout_height"=fill_parent "
android:orientation"=vertical ">
<TextView android:id"=@+id/text "
android:layout_width"=wrap_content "
android:layout_height"=wrap_content "
android:text"=Hello, I am a TextView/ ">
<Button android:id"=@+id/button "
android:layout_width"=wrap_content "
android:layout_height"=wrap_content "
android:text"=Hello, I am a Button/ ">
</LinearLayout>
Load the XML Resource
The XML layout file is compiled into a View resource
The layout resource is loaded in the [Link] ((
method
The layout resource is loaded by calling setContentView ((
and passing the reference to the layout resource
the layout resource reference is [Link].layout_file_name
Cont’d…
public void onCreate )Bundle savedInstanceState){
[Link](savedInstanceStat);
setContentView([Link].main_layout);
}
Attributes
Every View and ViewGroup object supports their own
variety of XML attributes
Some attributes are specific to a View object ; these
attributes are inherited by any View objects that extend
this class
Some attributes are common to all View objects, because
they are inherited from the root View class
Other attributes are considered "layout parameters "that
describe certain layout orientations of the View object
ID attribute
Any View object may have an integer ID
uniquely identify the View within the tree
the ID is typically assigned in the layout XML file as a
string
This attribute is common to all View objects
android:id"=@+id/my_button"
➢ The “+” indicates that this ID should be created if it doesn’t exist.
Using the ID
The syntax for an ID, inside an XML tag is:
android:id"=@+id/my_button"
Referencing an Android resource ID:
If the ID is already defined elsewhere, like in a styles or another
layout, you can reference it without the “+”.
android:id="@android:id/my_button"
In the [Link] file:
<Button android:id"=@+id/my_button "
android:layout_width"=wrap_content "
android:layout_height"=wrap_content "
android:text"=@string/my_button_text/">
In the java code:
Button myButton = (Button)
findViewById([Link].my_button);
Using Views
Set properties: for example, setting the text of a TextView.
properties that are known at build time can be set in the XML
layout files.
Set focus: The framework will handle moving focus in
response to user input. To force focus to a specific view, call
requestFocus().
Set up listeners: Views allow clients to set listeners that will be
notified when something interesting happens to the view. Such
as notified when the view gains or loses focus.
Set visibility: You can hide or show views using
setVisibility(int).
Position
View geometry is that of a rectangle
View location expressed as a pair of left and top coordinates and two
dimensions, expressed as a width and a height
The unit for location and dimensions is the pixel
retrieve the location:
getLeft ((
getTop((
getRight ((
getBottom((
View size
expressed with a width and a height
possess two pairs of width and height values:
How big a view wants to be within its parent: measured
width & height
The actual size of the view on screen: width and
height
measured width and measured height
Text Views
Text View
Edit Text
Auto Complete Text View
Multi auto Complete text View
Text View
Extends View
Displays text to the user and optionally allows them to edit it
TextView is a complete text editor, however the basic class is
configured to not allow editing
[Link]
Using Linkify with a Text View
TextView tv =(TextView)
[Link]([Link]);
[Link]("Please visit my website,
[Link]
or email me at
sayed@[Link].");
[Link](tv, [Link]);
Edit Text
Extends TextView
EditText is a thin veneer over TextView that configures itself to be
editable
Properties:
capitalize to have the control capitalize words, the beginning of
sentences
phoneNumber property if you need to accept a phone number
password property if you need a password field
single line by setting the singleLine property to true
Auto Complete text View
TextView with auto-complete functionality. the control display
suggestions for the user to select
AutoCompleteTextView actv = (AutoCompleteTextView)
[Link]([Link]);
ArrayAdapter<String> aa = new
ArrayAdapter<String>(this,
[Link].simple_dropdown_item_1line,
new String[] {"English", "Hebrew", "Hindi",
"Spanish", "German","Greek" });
[Link](aa);
Buttons
Simple Button
Image Button
Toggle Button
Check Box
Radio Button
Button
Button represents a push-button widget
Extends TextView
Push-buttons can be pressed, or clicked, by the user
to perform an action
A typical use of a push-button in an activity would be
the following :
final Button button ( =Button )
findViewById([Link].button_id);
[Link](new [Link] )({
public void onClick(View v ){ //Perform action on
click } });
Button XML declaration
<Button android:id="@+id/ccbtn1"
android:text="@+string/basicBtnLabel"
android:typeface="serif"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Image Button
<ImageButton
android:id="@+id/imageBtn"
android:src="@drawable/btnImage"
android:layout_width="wrap_content
"
android:layout_height="wrap_conten
t"/>
ImageButton btn =
(ImageButton)[Link]([Link]
eBtn);
[Link]([Link]);
Toggle Button
Two-state button
This button can be in either the On state or the Off state
<ToggleButton android:id="@+id/cctglBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Run"
android:textOff="Stop"
android:text="Toggle Button"/>
Check Box
Two-state button that allows the user to toggle its state
setChecked()
toggle()
isChecked()
setOnCheckedChangeListener()
onCheckedChanged()
<CheckBox android:text=“CheckBox"
android:layout_width="wrap_conten
t"
android:layout_height="wrap_conte
nt" />
Radio Button
First create a RadioGroup and then populate the group with radio
buttons
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton android:id="@+id/chRBtn"
android:text="Chicken"
<RadioButton android:id="@+id/fishRBtn"
android:text="Fish"
</RadioGroup>
Layout Managers
containers for views
manage the size and position of its children
ConstraintLayout position and size widget in a flexible way.
LinearLayout Organizes horizontally or vertically.
TableLayout Organizes in tabular form
RelativeLayout Organizes its children relative to one another or
to the parent
AbsoluteLayout Positions based on exact coordinates
FrameLayout Allows to dynamically change the control(s) in
the layout
Linear Layout
manager organizes its children either horizontally or vertically based
on the value of the orientation property
<LinearLayout xmlns:android=“…"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!-- add children here-->
</LinearLayout>
Gravity vs Layout Gravity
Android:gravity is a setting used by the view
Android:layout_gravity is used by the container
Dimension
You could specify the dimensions in any of the following
units:
px: Pixels
in: Inches
mm: Millimeters
pt: Points
dp: Density-independent pixels based on a 160-dpi (pixel density per
inch) screen (dimensions adjust to screen density)
sp: Scale-independent pixels (dimensions that allow for user sizing;
helpful for use in fonts)
Table Layout
extension of LinearLayout
This layout structures its child controls into rows and columns
<TableLayout xmlns:android=“…"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableRow>
<TextView … />
<EditText … />
</TableRow>
<TextView … />
<EditText … />
</TableRow>
</TableLayout>
Relative Layout
implements a policy where the
controls in the container are laid
out relative to either the container
or another control in the container
Relative Layout
<RelativeLayout xmlns:android=“…"
<TextView android:id="@+id/userNameLbl"
android:layout_alignParentTop="true" />
<EditText android:id="@+id/userNameText"
android:layout_below="@id/userNameLbl" />
<TextView android:id="@+id/pwdLbl"
android:layout_below="@id/userNameText" />
<EditText android:id="@+id/pwdText"
android:layout_below="@id/pwdLbl"/>
<TextView android:id="@+id/pwdHintLbl"
android:layout_below="@id/pwdText"/>
<TextView android:id="@+id/disclaimerLbl"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Absolute Layout
allows you to specify the exact position for the controls in the
container.
<AbsoluteLayout …>
<TextView android:text="Username:"
android:layout_x="50px"
android:layout_y="50px" />
<EditText
android:layout_x="160px"
android:layout_y="50px" />
<TextView android:text="Password:"
android:layout_x="50px"
android:layout_y="100px" />
</AbsoluteLayout>
Using Absolute Layout
public void
Programmatically
onCreate(Bundle icicle)
{
[Link](icicle);
ImageView img = new ImageView(this);
imgsetImageResource([Link]
e);
AbsoluteLayout al = new
AbsoluteLayout(this);
[Link](img,
new [Link](
50, // width
50, //height
0, //left
0); //top
SetContentView(al);
Frame Layout
mainly used to display a single item
You mainly use this utility layout class to dynamically display a
single view
but you can populate it with many items, setting one to visible while
the others are nonvisible
Frame Layout
<FrameLayout …>
<ImageView …
android:id="@+id/oneImgView"
android:src="@drawable/one" />
<ImageView …
android:id="@+id/twoImgView"
android:src="@drawable/two"
android:visibility="gone" />
</FrameLayout>
@Override
protected void onCreate(Bundle savedInstanceState) {
…
setContentView([Link]);
ImageView one =
(ImageView)[Link]([Link]);
ImageView two =
(ImageView)[Link]([Link]);
[Link](new OnClickListener(){
@Override
public void onClick(View view) {
ImageView two =
(ImageView)[Link].
findViewById([Link]);
[Link]([Link]);
[Link]([Link]);
}});
[Link](new OnClickListener(){
@Override
public void onClick(View view) {
ImageView one = (ImageView)FramelayoutActivity.
[Link]([Link]);
[Link]([Link]);
[Link]([Link]);
List Controls
The ListView control displays a list of items vertically
Generally use a ListView by writing a new activity that extends
[Link]
setListAdapter set the data for the ListView
@Override
protected void onCreate(Bundle savedInstanceState)
{
[Link](savedInstanceState);
Cursor c =
getContentResolver().query(People.CONTENT_URI,
null, null, null, null);
startManagingCursor(c);
String[] cols = new String[]{[Link]};
int[] names = new int[]{[Link].row_tv};
adapter = new
SimpleCursorAdapter(this,[Link],c,cols,names)
;
[Link](adapter);
}
}
Adapters
Adapters are used for binding data to a control
Adapters are employed for widgets that extend
[Link]:
ListView
GridView
Spinner
Gallery
Adapters Classes Hierarchy
View
ViewGroup
AdapterView
ListView GridView Spinner Gallery
Array Adapter
It specifically targets list controls
Assumes that TextView controls represent the list items
Displays text only using to toString() of its elements
Array Adapter Constructor
public ArrayAdapter (Context context, int
textViewResourceId, T[] objects)
context The current context
resource The resource ID for a layout file containing a
layout to use when instantiating views
textViewResourceId The id of the TextView within the
layout resource to be populated
objects The objects to represent in the ListView
Creating Array Adapter from string
resource
adapter = [Link](this,
[Link],[Link]);
Creating Strings Resource Array
<string-array name="planets">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
<item>Mars</item>
<item>Jupiter</item>
<item>Saturn</item>
<item>Uranus</item>
<item>Neptune</item>
<item>Pluto</item>
</string-array>
Simple Array Adapter
Easy adapter to map static data to views defined in an
XML file
You can specify the data as an ArrayList of Maps
Each entry in the ArrayList corresponds to one row in the
list
The Maps contain the data for each row
You also specify an XML file that defines the views used
to display the row
Define mapping from keys in the Map to specific views
public SimpleAdapter (Context context,
List<? extends Map<String, ?>> data,
int resource, String[] from, int[] to)
Parameters
Context: The context the View associated with
Data: List of Maps. Each entry in the List corresponds to
one row in the list.
Resource: view layout that defines the views for this list
item.
From: A list of column names
To: The views that should display column in the "from"
parameter.
Grid Controls
displays items in a two-dimensional, scrolling grid .
The items are acquired from a ListAdapter.
private class ItemsAdapter extends ArrayAdapter<Item> {
private Item[] items;
public ItemsAdapter(Context context, int textViewResourceId, Item[]
items) {
super(context, textViewResourceId, items);
[Link] = items;
}
@Override
public View getView(int position, View convertView, ViewGroup
parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi =
(LayoutInflater)getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = [Link]([Link].items_list_item, null);
}
Item it = items[position];
if (it != null) {
ImageView iv = (ImageView)
[Link]([Link].list_item_image);
if (iv != null) {
[Link]([Link]());
}
}
return v;
}
}
▪ Introduction
▪ Preparing containers and components
▪ Management of component layout
▪ Event handling
UI Events and Listeners
Listeners are an important aspect when developing UIs in Android.
Generally speaking, when an user interacts with our app
interface, the system “creates” some events.
Each view that builds our interface is capable of generating events
and providing the means to handle them.
From an API point of view, if we look at a View class, we can notice
there are some public methods; these methods are called by the
system when some events occur.
They are called callback methods, and they are the way we can
capture the events that occur while an user interacts with our app.
Usually these callback methods starts with on + event_name.
Cont’d…
Every View provides a set of callback methods.
Some are common between several views while others are view-
specific.
Anyway, in order to use this approach, if we want to catch an event,
we should extend the View and this is clearly not practical.
For this reason, every View has a set of interfaces that we have to
implement in order to be notified about the events that occur.
These interfaces provide a set of callback methods.
We call these interfaces as event listeners.
Therefore, for example, if we want to be notified when a user clicks
on a button we have an interface to implement called
[Link].
Cont’d…
Let us consider the example above when we used a Button in our
UI.
If we want to add a listener, the first thing we have to do is to get a
reference to the Button:
Button b = (Button)findViewById([Link]);
In our Activity there is a method called findViewById that can be
used to get the reference to a View defined in our user interface.
Once we have the reference, we can handle the user click:
Cont’d…
[Link](new [Link]()
{
@Override
public void onClick(View v) {
// here we handle the event
}
});
Cont’d…
As you can see in the above example we used a compact form and
you can notice the callback method called onClick.
This method is called by the system when a user clicks on our
button, so here we have to handle the event.
We could obtain the same result in a different way: we can make our
Activity implement the [Link] interface and
implement onClick again.
~~~~~ The End ~~~~~
Android UI Hierarchy with Major Components
Android UI Hierarchy with Major Components