Android Programming: Widget Event Handling: For Live Android Training, Please See Courses
Android Programming: Widget Event Handling: For Live Android Training, Please See Courses
Android Programming:
Widget Event Handling
Originals of Slides and Source Code for Examples:
http://www.coreservlets.com/android-tutorial/
Summary of Layout
Button
Button
Button
Horizontal RadioGroup
(Containing 3 RadioButtons)
Vertical
LinearLayout
TextView
(No text, but controls will
change the background
color of this region.) An upcoming tutorial section gives details on using layouts. However,
you can do a pretty lot now by knowing just two simple things:
res/layout/main.xml (Continued)
<RadioGroup
android:gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radio_button1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/red_prompt"/>
A horizontal RadioGroup gives the same layout
<RadioButton as a horizontal LinearLayout, except that it
android:id="@+id/radio_button2" contains only RadioButtons. A RadioGroup also
means that only one of the RadioButtons inside
android:layout_height="wrap_content" can be selected at any given time.
android:layout_width="wrap_content"
android:text="@string/blue_prompt"/>
<RadioButton
android:id="@+id/radio_button3"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/yellow_prompt"/>
10 </RadioGroup>
res/layout/main.xml (Continued)
<TextView
android:id="@+id/color_region"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</LinearLayout>
11
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Event Handling Example</string>
<string name="red_prompt">Red</string>
<string name="blue_prompt">Blue</string>
<string name="yellow_prompt">Yellow</string>
</resources>
Each string is used as label for one Button and one RadioButton.
12
Main Activity Class
This part just looks up the
public class Events1Example extends Activity { controls that were defined in
private View mColorRegion; main.xml, and assigns them to
variables. Note the Android
coding convention that non-public
instance variables (data
@Override members) start m.
14
Event Handler Class
public class ColorSetter implements OnClickListener {
private int regionColor;
private Events1Example mainActivity;
@Override
public void onClick(View v) {
mainActivity.setRegionColor(regionColor);
}
} Event handler must store a reference to the main Activity so that it can call
back to it. Another option in this particular case would be to pass the TextView
15
to the event handler, but passing the main Activity is a more general solution.
Results on Emulator
16
Results on Physical Phone
17
XML Files:
Same as Previous Example
res/layout/main.xml
Defines vertical LinearLayout that contains 3 Buttons, a
horizontal RadioGroup (with 3 RadioButtons), and a
TextView.
The Buttons, RadioButtons, and TextView have ids so
that they can be referred to in the Java code
res/values/strings.xml
Defines the app name and the labels of the Buttons and
RadioButtons
20
Main Activity Class
Except for the class name, this
public class Events2Example extends Activity { top part of the Activity is exactly
private View mColorRegion; the same as the previous
example.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mColorRegion = findViewById(R.id.color_region);
Button b1 = (Button)findViewById(R.id.button1);
Button b2 = (Button)findViewById(R.id.button2);
Button b3 = (Button)findViewById(R.id.button3);
RadioButton r1 =
(RadioButton)findViewById(R.id.radio_button1);
RadioButton r2 =
(RadioButton)findViewById(R.id.radio_button2);
RadioButton r3 =
(RadioButton)findViewById(R.id.radio_button3);
21
@Override
public void onClick(View v) {
setRegionColor(regionColor);
}
}
Event handler can directly call methods in the main
} Activity, even if the method is private.
23
Results on Emulator
Same as previous example.
24
Results on Physical Phone
Same as previous example.
25
Using an Anonymous
Inner Class for Event
Handling
Customized Java EE Training: http://courses.coreservlets.com/
Java, JSF 2, PrimeFaces, Servlets, JSP, Ajax, jQuery, Spring, Hibernate, RESTful Web Services, Hadoop, Android.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Idea
Goal
Randomly change color of TextView when Button is pressed.
Approach
Use an anonymous inner class that implements the Listener
Advantages
Assuming that each class is applied to a single control only,
same advantages as named inner classes, but shorter.
This approach is widely used in Swing, SWT, AWT, and GWT.
Disadvantages
If you applied the handler to more than one control, you would
have to cut and paste the code for the handler.
This approach should be applied for a single control only
If the code for the handler is long, it makes the code harder to
read by putting it inline.
27 This approach is usually used only when handler code is short
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/color_button"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="@string/button_prompt"/>
<TextView
android:id="@+id/color_region"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</LinearLayout>
28
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Event Handling Example</string>
<string name="button_prompt">Random Color</string>
</resources>
29
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mColorRegion = findViewById(R.id.color_region);
Button colorButton =
(Button)findViewById(R.id.color_button);
colorButton.setOnClickListener(new ColorRandomizer());
}
There is nothing wrong with this approach.
However, this event handler class is only
used on this line of code. Furthermore, the
private void setRegionColor(int color) { code for ColorRandomizer (next page) is
relatively short. So, you can make it a bit
mColorRegion.setBackgroundColor(color); more concise with an anonymous inner
30
} class.
Main Activity Class Attempt 1:
Named Inner Class (Continued)
private class ColorRandomizer
implements OnClickListener {
@Override
public void onClick(View v) {
Random generator = new Random();
int index = generator.nextInt(mColorChoices.length);
setRegionColor(mColorChoices[index]);
}
}
}
31
32
Main Activity Class Refactored:
Anonymous Inner Class (Cont.)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mColorRegion = findViewById(R.id.color_region);
Button colorButton =
(Button)findViewById(R.id.color_button);
colorButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Random generator = new Random();
int index = generator.nextInt(mColorChoices.length);
setRegionColor(mColorChoices[index]);
}
}); This defines the class and instantiates it all in one fell swoop. If you have never seen anonymous
inner classes before, the confusion is probably not worth the code savings over a named inner
} class. However, once you are used to it, it is more concise and arguably easier to understand
because the behavior is shown where it is used. This approach is very commonly used by Swing,
SWT, AWT, and GWT programmers. This is also very analogous to anonymous functions
(closures) that are widely used in functional programming languages.
33
Results on Emulator
34
Results on Physical Phone
35
37
XML Files:
Same as Previous Example
res/layout/main.xml
Defines vertical LinearLayout that contains a Button and
a TextView.
The Button and TextView have ids so that they can be
referred to in the Java code
res/values/strings.xml
Defines the app name and the label of the Button
38
Main Activity Class
public class Events5Example extends Activity
implements OnClickListener {
private View mColorRegion;
private int[] mColorChoices =
{ Color.BLACK, Color.BLUE, ... };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mColorRegion = findViewById(R.id.color_region);
Button colorButton =
(Button)findViewById(R.id.color_button);
colorButton.setOnClickListener(this);
}
39
@Override
public void onClick(View v) {
Random generator = new Random();
int index = generator.nextInt(mColorChoices.length);
setRegionColor(mColorChoices[index]);
}
}
40
Results on Emulator
Same as previous example.
41
42
2012 Marty Hall
Handling Events by
Specifying the Event
Handler Method in
main.xml
Customized Java EE Training: http://courses.coreservlets.com/
Java, JSF 2, PrimeFaces, Servlets, JSP, Ajax, jQuery, Spring, Hibernate, RESTful Web Services, Hadoop, Android.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Idea
Goal
Randomly change color of TextView when Button is pressed.
Same as previous example
Approach
Put the handler method in the main Activity. Do not implement a Listener interface or call
setOnClickListener. Have the layout file (main.xml) specify the handler method via the
android:onClick attribute.
Advantages
Assuming that the app has only a single control of that Listener type, mostly the same
advantages (short/simple code) as the previous approach where the Activity implemented the
interface.
More consistent with the do layout in XML strategy
You can supply different method names for different controls, so not nearly as limited as
interface approach.
Disadvantages
You cannot pass arguments to Listener.
Less clear to the Java developer which method is the handler for which control
Since no @Override, no warning until run time if method is spelled wrong or has wrong
argument signature
44
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/color_button"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="@string/button_prompt"
android:onClick="randomizeColor"/>
<TextView
android:id="@+id/color_region" This is the name of the event
handler method in the main class.
android:layout_height="match_parent" This method must have a void
android:layout_width="match_parent"/> return type and take a View as an
argument. However, the method
</LinearLayout> name is arbitrary, and the main
class need not implement any
particular interface.
45
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Event Handling Example</string>
<string name="button_prompt">Random Color</string>
</resources>
46
Main Activity Class
public class Events6Example extends Activity {
private View mColorRegion;
private int[] mColorChoices =
{ Color.BLACK, Color.BLUE, ... };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mColorRegion = findViewById(R.id.color_region);
// No need to look up the button or assign event handler
}
47
48
Results on Emulator
Same as previous example.
49
50
2012 Marty Hall
Wrap-Up
Questions?
JSF 2, PrimeFaces, Java 7, Ajax, jQuery, Hadoop, RESTful Web Services, Android, Spring, Hibernate, Servlets, JSP, GWT, and other Java EE training.