Translation of Android Teaching Slides from Cleveland State University
The View Class
The View class serves as a fundamental building block for UI components.
A View encapsulates a rectangular area on the screen and is responsible for drawing and event handling.
Views are a base class for widgets, which are used to create interactive UI elements (like buttons, text fields, etc.).
The subclass ViewGroup
is a base class for layouts, acting as a container that holds Views (or other ViewGroups) and defines their layout properties.
All views within a window are organized in a single tree structure.
You can add views programmatically or by defining a tree of views in one or more XML layout files.
Once you create a tree of views, there are several typical operations you may perform:
- Set Properties: For example, setting text in a TextView. Properties known at build time can be specified in the XML layout file.
- Set Focus: The framework manages focus movement in response to user input. To focus on a specific view, call
requestFocus()
. - Set Up Listeners: Views allow clients to set up listeners that get notified when an interaction occurs. For instance, a Button will notify clients when it is clicked.
- Set Visibility: You can show or hide views using
setVisibility(int)
.
Some Basic UI Components
- Linear Layout: A LinearLayout is a ViewGroup that arranges its child Views either horizontally or vertically.
- Relative Layout: A RelativeLayout is a ViewGroup that allows you to position a child relative to its parent or to sibling components.
- Table Layout: A TableLayout is a ViewGroup that arranges its child Views in rows and columns.
- DatePicker: A DatePicker is a widget that enables users to select a date.
- Form Controls: This includes various types such as images, buttons, text fields, checkboxes, and radio buttons.
- AutoCompleteTextView: This is a version of the EditText widget that provides auto-complete suggestions as the user types. These suggestions are sourced from strings.
- ListView: A ListView is a View that displays items in a vertical scrollable list. Items are sourced from a
ListAdapter
.
What is XML?
An XML-based layout is a structure (widgets) consisting of various UI elements and the relationships between them, all defined in XML format.
Android treats XML-based layouts as resources, and these files are stored in the res/layout
directory of the Android project.
You can use UI tools to create XML layout files.
Each XML file contains a tree structure explicitly defining the layout of widgets and containers that form a View.
The properties of XML components describe the design and behavior of widgets and containers.
For instance, if a Button has the property:
android:textStyle = "bold"
This means the text displayed on the button will render in bold font.
Here's an example application that creates a button that takes up the entire screen. When clicked, it displays the current time.
import java.util.Date;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class AndDemo extends Activity {
Button btn;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.myButton);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
updateTime();
}
});
} // onCreate
private void updateTime() {
btn.setText(new Date().toString());
}
}
This is the layout in XML format:
<?xml version="1.0" encoding="utf-8"?>
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myButton"
android:text=""
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
The root element needs to declare the Android XML namespace:
xmlns:android="http://schemas.android.com/apk/res/android"
All components will be children of the root or will inherit from the namespace declaration.
Since we want to reference this button from Java code, we need to give it an identifier through the android:id
attribute.
The other attributes pertain to the Button instance, such as text
, width
, and height
.
UI Hierarchy
HierarchyViewer displays the UI structure of the currently shown screen on an emulator or device.
Android Layout
Each element in an XML layout is either a View or a ViewGroup object.
Displaying the Application View
The Android UI framework renders the screen by traversing the View tree and asking each component to draw itself in a pre-order traversal manner. This is a tree traversal method; if you're curious about the algorithm, feel free to research it further.
Each component draws itself, and then recursively instructs its child components to do the same.
Common Layouts
There are five basic layout types: Frame, Linear, Relative, Table, and Absolute.
FrameLayout: FrameLayout is a very simple layout object. It is essentially an empty space on the screen where you can place any object, for example, an image. All child components of FrameLayout are pinned to the top-left corner of the screen; you don’t need to specify exact positions for child views. Subsequent child views will simply overlay on top of the previous ones, either partially or entirely.
LinearLayout: A LinearLayout arranges all its child Views in a single direction—either horizontally or vertically, based on the
android:orientation
attribute. Each child view stacks sequentially: vertical will have one item per line, and horizontal will have one item per column. A LinearLayout allows for margins between children and gravity (left, right, center) for each child. You can also add aweight
attribute to children of LinearLayout; each weight value impacts how much space a View should expand to fill any remaining empty space in the parent View.TableLayout: TableLayout organizes children into rows and columns. The TableLayout container will not display line borders. Here’s an example of TableLayout showing 2 rows and 2 cells in each row, with dotted borders around the cells.
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="*">
<TableRow>
<TextView android:text="Open…"
android:padding="3dip" />
<TextView android:text="Ctrl-O"
android:gravity="right"
android:padding="3dip" />
</TableRow>
<TableRow>
<TextView android:text="Save As…"
android:padding="3dip" />
<TextView android:text="Ctrl-Shift-S"
android:gravity="right"
android:padding="3dip" />
</TableRow>
</TableLayout>
RelativeLayout: A RelativeLayout allows child views to position themselves relative to their parent or to one another. You can align two components by their
right border
, or position thembelow
,centered
, etc. Components are rendered in the order given, so if one component is centered on the screen, the other components will align relative to that center point. Due to this ordering, when using XML to define a layout, components you wish to reference will need to be listed in the XML file before you can reference them from other views using their IDs.AbsoluteLayout: This layout allows you to specify the exact location (x/y coordinates) for child views. Absolute layouts are less flexible and harder to maintain than layouts that don't require absolute positioning.
Attaching Layouts to Java Code
Finally, you need to connect the components in XML to their corresponding objects in your Java activity. Only then can you manipulate the UI elements in code.
Assuming the UI is in res/layout/main.xml
, you can call this layout using:
setContentView(R.layout.main);
A specific widget, for instance, myButton
, can be accessed by the application through findViewById(...)
like this:
Button btn = (Button) findViewById(R.id.myButton);
R is an automatically generated class that maintains a record of available resources for the application. Specifically, R.id...
is a collection of widgets defined in the XML layout.
Attach Listeners to Widgets
The button in our example can now be utilized; for instance, a listener for a click event can be written as follows:
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
updateTime();
}
});
private void updateTime() {
btn.setText(new Date().toString());
}
Basic Widgets: Labels
A label is known as a TextView. TextViews are typically used to display captions and cannot be edited.
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="@+id/absLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/myTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff0000ff"
android:padding="3px"
android:text="Enter User Name"
android:textSize="16sp"
android:textStyle="bold"
android:gravity="center"
android:layout_x="20px"
android:layout_y="22px" />
</AbsoluteLayout>
Basic Widget: Buttons
A Button triggers an action click in the GUI. A Button is a subclass of TextView, so formatting Buttons is quite similar to TextView.
Basic Widget: Images
ImageView and ImageButton are two widget components in Android that allow you to incorporate images into your application. Both widgets are quite similar to TextView and Button. Each widget has the android:src
or android:background
property in the XML layout to specify which image to use. Images are typically located in the drawable resources. ImageButton is a subclass of ImageView and adds properties to respond to click events like a Button.
Basic Widgets: EditText
An EditText (or text box) is an extension of TextView that allows you to edit and update text content.
Basic Widgets: CheckBoxes & RadioButtons
For this section, focus on understanding the concepts. Delving deeper into the code content may take considerable time and require a more in-depth report.
UI - Other Features
All widgets extend from View, allowing them to inherit many properties and methods of Views, including:
XML Controls the Focus Sequence:
android:visibility
android:background
Java Methods:
myButton.requestFocus()
myTextBox.isFocused()
myWidget.setEnabled()
myWidget.isEnabled()