5-5 More Widgets

To wrap up this introduction to Android app development we’ll look at a few more common Android widgets and how to handle their events.

To demonstrate the following examples I’ve started a new Android project called “Widget Playground” with an Empty Activity (and no backward compatibility).  Your starting XML code should look something like this:

CheckBox Widgets

In 4-4 we learned about the JCheckBox widget.  Android supports a similar CheckBox widget.  Drag and drop a CheckBox (from the Buttons group) followed by TextView widget onto the layout.  Feel free to adjust their visual properties.  Your XML layout should now look something like this:

Ensure that the ID property for the CheckBox widget is checkBox (line 10), and use checkBoxStatusView for the TextView widget (line 23).  If you don’t do this the Java code that follows will need adjustments.  Notice on line 16 that I have set the default status of the checkBox to true, meaning it’s checked.

Now edit the MainActivity.java file.  Start by adding the following imports for our two widgets and the OnClickListener interface for the CheckBoxCheckBox event handling works the same way as with Button widgets.

Within the MainActivity class, add instance variables for both widgets:

Within the onCreate() method, point our widget reference variables to the widget objects.

Create an inner class to implement the onClick() method of the OnClickListener interface:

Notice in the onClick() method that I am verifying that it was our checkBox that was clicked.  Since we only have one, this is obviously unnecessary but I’m including it in this example to demonstrate how you could handle more than one CheckBox using the same event listener.  The isChecked() method returns true or false depending on the status of the CheckBox widget.

Finally, we need to set the event listener for our checkBox widget.  Add the following lines to the end of the onCreate() method:

That’s all there is to it — try running it!

SeekBar Widgets

A SeekBar widget allows a user to specify an integer value by dragging a “thumb” to the right or left.

Add a SeekBar (ID: seekBar) and another TextView (ID: seekBarStatusView) widget to our layout:

The SeekBar widget has a max property to specify its maximum integer value, and a progress property to set the initial value of the SeekBar.  In this example our seekBar will support an integer range from 0 to 100, and the “thumb” will start in the middle at 50.

Next, add the following imports to our MainActivity.java file:

Add instance variables for the new widgets:

In the onCreate() method add code to initialize the instance variables to refer to the new widgets:

To handle SeekBar events we need to implement the OnSeekBarChangeListener interface which requires 3 methods.

The onProgressChanged() method is called continuously as the user changes the value of the SeekBar.  The progress parameter indicates the current value of the SeekBar.  The onStartTrackingTouch() and onStopTrackingTouch() methods are called when the user starts and finishes changing the SeekBar, respectively.  In this example, I am not implementing code for these last two methods, but must include them with empty method bodies.

Finally, we need to set the event listener for our seekBar widget.  Add the following line to the end of the onCreate() method:

Although the event listening interface is different, the implementation pattern is pretty similar for most widgets.

Spinner Widgets

Android supports a Spinner widget that provides functionality similar to the JComboBox (i.e., drop-down list) in Swing.

Drag and drop a Spinner (ID: spinner) widget (from the Containers group) followed by TextView (ID: spinnerStatusView) widget onto the layout.  Your design XML layout should now include the following:

To provide the list of options that will appear in the Spinner, we need to define an array of strings in the app > res > values > strings.xml file:

The Java code changes are a little more complex than the other widgets we’ve learned so far, but the pattern is similar.  Start by importing the following widget classes:

And the following two classes for event handling:

Add the following instance variables for our widgets:

And initialize them in the onCreate() method:

Next, we need to instantiate an ArrayAdapter class to link our spinner widget with the spinner_options array we defined earlier.  Add the following code to the onCreate() method:

Next, create an inner class to implement the onItemSelected() method of the OnItemSelectedListener interface:

You may have noticed the strange <?> generic syntax above.  The <?> is a wildcard that means the type of the object is not specified or unknown.  This makes it possible to support any Object (or subclass of Object).

Finally, we need to set the event listener for our spinner widget.  Add the following line to the end of the onCreate() method:

 

WebView Widgets

One last widget!  One of the apps I use several times a day is a weather app, but it’s user interface has very few Android widgets.  Instead, the app is essentially a viewer for a weather HTML page that includes lovely graphics and JavaScript code to give it interactivity.  This means that the content and user interface for the app can be changed on the backend (i.e., web server) easily and at any time without having to update the app on my device.  Let’s add a WebView widget to see how this works!

First, we need to permit our app to access the Internet.  Add the following line to the app > manifests > AndroidManifest.xml file, just before the <application> tag.

Next, drag a WebView (ID: webBrowser) widget to our layout.

Add the following import to our MainActivity.java file:

Add an instance variable for the new widget:

In the onCreate() method, initialize the reference variable to point to the WebView widget:

Finally, configure our webBrowser to support JavaScript and to load URLs into our widget instead of opening the default browser app on the device.

To load a web page into our webBrowser widget:

You Try!

  1. Add an ImageButton widget to our WidgetPlayground app. Find and add an image to the res > drawable folder as we did in 5-2ImageButton widgets use the same OnClickListener interface as Button and CheckBox  When the ImageButton is clicked, use the Toast.makeText() method to display an appropriate status message.  Note that the first argument to this method call must be MainActivity.this (not just this).
  2. Add a CheckBox to our TipCalculator app to control whether the final total should be rounded up to the nearest dollar or not.
  3. Replace the decreaseButton and increaseButton in our TipCalculator app with a SeekBar to control the tip percentage (0% to 20%), start at 15%.