Android Tutorial: UI Components

One of the first things you do when creating an Android application is build the user interface (UI) for the main activity. This is a relatively easy task thanks to the ready-to-use UI components that Android provides.

This chapter discusses some of the more important UI components.

Overview

The Android SDK provides various UI components called widgets that include many simple and complex components. Examples of widgets include buttons, text fields, progress bars, etc. In addition, you also need to choose a layout for laying out your UI components. Both widgets and layouts are implementations of the class. A view is a rectangular area that occupies the screen. View is one of the most important Android types. However, unless you are creating a custom view, you don’t often work with this class directly. Instead, you often spend time choosing and using layouts and UI components for your activities.

Figure 1.1 shows some Android UI components.

Using the Android Studio UI Tool

Creating a UI is easy with Android Studio. All you need is open the layout file for activity and drag and drop UI components to the layout. The activity files are located in the res/layout directory of your application.

Figure 1.2 shows the UI tool for creating Android UI. This is what you see when you open an activity file. The tool window is divided into three main areas. On the left are the widgets, which are grouped into different categories such as Layouts, Widgets, Text Fields, Containers, etc. Click on the tab header of a category to see what widgets are available for that category.

To choose a widget, click on the widget and drag it to the activity screen at the center. The screen in Figure 1.2 shows two text fields and a button. You can also view how your screen will look like in different devices by choosing a device from the Devices drop-down.

Each widget and layout has a set of properties derived from the View class or added to the implementation class. To change any of these properties, click on the widget on the drawing area or select it from the Outline pane in the Structure window on the right. The properties are listed in the small pane under the Layout pane.

What you do with the UI tool is reflected in the layout file, in the form of XML elements. To see what has been generated for you, click the XML view at the bottom of the UI tool.

Using Basic Components

The Basic Components project is a simple Android application with one activity. The activity screen contains two text fields and a button.

You can either open the accompanying application or create one yourself by following the instructions in Android Tutorial: Environment Setup. I will explain this project by presenting the manifest for the application, which is an XML file named AndroidManifest.xml located directly under the root directory.

Shows the AndroidManifest.xml for the BasicComponents project.

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.basiccomponents"
android:versionCode="1"
android:versionName="1.0">

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.basiccomponents.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category
android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

The first thing to note is the package attribute of the manifest tag, which specifies com.example.basiccomponents as the Java package for the generated classes. Also note that the application element defines one activity, the main activity. The application element also specifies the icon, label, and theme for this application.

android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">

It is good practice to reference a resource (such as an icon or a label) indirectly, like what I am doing here. @drawable/ic_launcher , the value for android:icon , refers to a drawable (normally an image file) that resides under the res/drawable directory. ic_launcher can mean an ic_launcher.png or ic_launcher.jpg file.

All string references start with . In the example above, @string/app_name refers to the app_name key in the res/values/strings.xml file. For this application, the strings.xml file is given.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">BasicComponents</string>
<string name="action_settings">Settings</string>
<string name="prompt_email">Email</string>
<string name="prompt_password">Password</string>
<string name="action_sign_in"><b>Sign in</b></string></resources>

Let’s now look at the main activity. There are two resources concerned with an activity, the layout file for the activity and the Java class that derives from android.app.Activity . For this project, the layout file is given and the activity class (MainActivity).

The layout file

<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:layout_gravity="center"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="120dp"
tools:context=".MainActivity" >

<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:maxLines="1"
android:singleLine="true" />

<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="@+id/login"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />

<Button
android:id="@+id/sign_in_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="16dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:text="@string/action_sign_in" />

</LinearLayout>

The layout file contains a LinearLayout element with three children, namely two components and a button.

The MainActivity class of Basic Components

package com.example.basiccomponents;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it
// is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}

The MainActivity class is a boilerplate class created by Android Studio. It overrides the and onCreateOptionsMenu methods. is a lifecycle method that gets called when the application is created. It simply sets the content view for the activity using the layout file. onCreateOptionsMenuinitializes the content of the activity’s options menu. It must return true for the menu to be displayed.

Run the application and you’ll see the activity as shown in Figure 1.3.

Toast

A is a small popup for displaying a message as feedback for the user. A does not replace the current activity and only occupies the space taken by the message.

Figure 1.4 shows a Toast that says “Downloading file…” The Toast disappears after a prescribed period of time.

The android.widget.Toast class is the template for creating a . To create a Toast, call its only constructor that takes a Context as an argument:

public Toast(android.content.Context context)

also provides two static methods for creating an instance of Toast. The signatures of both method overloads are

public static Toast makeText (android.content.Context context, int resourceId, int duration) public static Toast makeText (android.content.Context context, java.lang.CharSequence text, int duration)

Both overloads require that you pass a , possibly the active activity, as the first argument. In addition, both overloads take a string, which may come from a strings.xml file or a String object, and the duration of the display for the Toast. Two valid values for the duration are the LENGTH_LONG and LENGTH_SHORT static finals in Toast.

To display a Toast, call its show method. This method takes no argument.

The following code snippet shows how to create and display a Toast in an activity class.

Toast.makeText(this, "Downloading...", Toast.LENGTH_LONG).show();

By default, a Toast is displayed near the bottom of the active activity. However, you can change its position by calling its setGravity method before calling its show method. Here is the signature of setGravity .

public void setGravity(int gravity, int xOffset, int yOffset)

The valid value for gravity is one of the static finals in the class, including CENTER_HORIZONTAL and CENTER_VERTICAL .

You can also enhance the look of a Toast by creating your own layout file and passing it to the Toast’s setViewmethod. Here is an example of how to create a custom .

LayoutInflater inflater = getLayoutInflater(); 
View layout=inflater.inflate(R.layout.toast_layout(ViewGroup)findViewById(R.id.toast_layout_root));
Toast toast = new Toast(getApplicationContext()); toast.setView(layout);
toast.show();

In this case, R.layout.toast_layout is the layout identifier for the Toast and R.id.toast_layout_root is the id of the root element in the layout file.

AlertDialog

Like a Toast, an AlertDialog is a window that provides feedback to the user. Unlike a that fades by itself, however, an AlertDialog shows indefinitely until it loses focus. In addition, an AlertDialog can contain up to three buttons and a list of selectable items. A button added to an AlertDialog can be connected to a listener that gets triggered when the button is clicked.

Figure 1.5 shows a sample AlertDialog.

The android.app. AlertDialog class is the template for creating an AlertDialog . All constructors in this class are protected, so you cannot use them unless you are subclassing the class. Instead, you should use the AlertDialog.Builder class to create an AlertDialog. You can use one of the two constructors of AlertDialog.Builder .

public AlertDialog.Builder(android.content.Context context) public AlertDialog.Builder(android.content.Context context, int theme)

Once you have an instance of AlertDialog.Builder , you can call its method to return an AlertDialog. However, before calling create you can call various methods of AlertDialog.Builder to decorate the resulting AlertDialog . Interestingly, the methods in AlertDialog.Builder return the same instance of AlertDialog.Builder , so you can cascade them. Here are some of the methods in AlertDialog.Builder .

public AlertDialog.Builder setIcon(int resourceId)

Sets the icon of the resulting AlertDialog with the Drawable pointed by resourceId .

public AlertDialog.Builder setMessage(java.lang.CharSequence message)

Sets the message of the resulting AlertDialog.

public AlertDialog.Builder setTitle(java.lang.CharSequence title)

Sets the title of the resulting AlertDialog.

public AlertDialog.Builder setNegativeButton( java.lang.CharSequence text, android.content.DialogInterface.OnClickListener listener)

Assigns a button that the user should click to provide a negative response.

public AlertDialog.Builder setPositiveButton( java.lang.CharSequence text, android.content.DialogInterface.OnClickListener listener)

Assigns a button that the user should click to provide a positive response.

public AlertDialog.Builder setNeutralButton( java.lang.CharSequence text, android.content.DialogInterface.OnClickListener listener)

Assigns a button that the user should click to provide a neutral response.

For instance, the following code produces an AlertDialog that looks like the one in Figure 1.5.

new AlertDialog.Builder(this) 
.setTitle("Please confirm")
.setMessage(
"Are you sure you want to delete " +
"this contact?")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int whichButton) {

// delete picture here

dialog.dismiss();
}
})
.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
dialog.dismiss();
}
})
.create()
.show();

Pressing the Yes button will execute the listener passed to the setPositiveButton method and pressing the No button will run the listener passed to the setNegativeButton method.

Notifications

A notification is a message on the status bar. Unlike a toast, a notification is persistent and will keep showing until it is closed or the device is shut down.

A notification is an instance of android.app.Notification . The most convenient way to create a notification is by using a nested class called Builder, which can be instantiated by passing a . You can then call the build method on the builder to create a Notification.

Notification n = new Notification.Builder(context).build();

The Notification.Builder class has methods to decorate the resulting notification. These methods include addAction, setAutoCancel , , setContent , setContentTitle , setContentIntent , setLargeIcon , setSmallIcon and .

Many of these methods are self-explanatory, but addAction and setContentIntent are of particular importance because you can use them to add an action that will be performed when the user touches the notification. In this case, a notification action is represented by a PendingIntent . Here are the signatures of and setContentIntent , both of which take a PendingIntent .

public Notification.Builder addAction(int icon,
java.lang.CharSequence title,
android.app.PendingIntent intent)
public Notification.Builder setContentIntent(
android.app.PendingIntent intent)

When the user touches the notification, the send method of the PendingIntent will be invoked. See the sidebar for a description of PendingIntent .

setAutoCancel is also important and passing true to it allows the notification to be dismissed when the user touches it on the notification drawer. The notification drawer is an area that opens when you slide down the status bar. The notification drawer shows all notifications that the system have received and have not been dismissed.

The methods in Notification.Builder return the same Builder object, so they can be cascaded:

Notification notification  = new Notification.Builder(context)
.setContentTitle("New notification")
.setContentText("You've got one!")
.setSmallIcon(android.R.drawable.star_on)
.setContentIntent(pendingIntent)
.setAutoCancel(false)
.addAction(android.R.drawable.star_big_on,
"Open", pendingIntent)
.build();

To sound a ringtone, flash lights and make the device vibrate, you can OR the defaults flags like so:

notification.defaults|= Notification.DEFAULT_SOUND; notification.defaults|= Notification.DEFAULT_LIGHTS; notification.defaults|= Notification.DEFAULT_VIBRATE;

In addition, to make repeating sound, you can set the FLAG_INSISTENT flag.

notification.flags |= Notification.FLAG_INSISTENT;

The PendingIntent Class

A PendingIntent encapsulates an Intent and an action that will be carried out when its send method is invoked. Since a PendingIntent is a pending intent, the action is normally an operation that will be invoked some time in the future, most probably by the system. For example, a PendingIntent can be used to construct a Notification so that something can be made happen when the user touches the notification.

The action in a PendingIntent is one of several methods in the class, such as startActivity , startService or sendBroadcast .

You have learned that to start an activity you can pass an Intent to the startActivity method on a Context.

Intent intent = ... context.startActivity(intent);

The equivalent code for starting an activity using a PendingIntent looks like this:

Intent intent = ... PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); pendingIntent.send();

The static method getActivity is one of several methods that returns an instance of PendingIntent . Other methods are getActivities , getService and getBroadcast . These methods determine the action that the resulting PendingIntent can perform. Constructing a PendingIntent by calling getActivity returns an instance that can start an activity. Creating a PendingIntent using getService gives you an instance that can be used to start a service. You call getBroadcast if you want a PendingIntent for sending a broadcast.

To publish a notification, use the NotificationManager , which is one of the built-in services in the Android system. As it is an existing system service, you can obtain it by calling the getSystemService method on an activity, like so:

NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

Then, you can publish a notification by calling the notify method on the NotificationManager , passing a unique ID and the notification.

notificationManager.notify(notificationId, notification);

The notification ID is an integer that you can choose. This ID is needed just in case you want to cancel the notification, in which case you pass the ID to the method of the NotificationManager :

notificationManager.cancel(notificationId);

The NotificationDemo project is an application that shows how to use notifications. The main activity of the app contains two buttons, one for publishing a notification and one for cancelling it. After the notification is published, opening it will invoke a second activity.

See full article here: https://www.djuices.com/android-tutorial-ui-components/

Originally published at https://www.djuices.com on November 22, 2021.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store