Interactions in Android
Overview
Event Listening in Android development is largely centered around the View
object.
View Event Listeners
Any View (Button, TextView, etc) has many event listeners that can be attached using the setOnEvent
pattern which involves passing a class that implements a particular event interface. The listeners available to any View
include:
In Xamarin instead of using the traditional interfaces for handling events, .NET uses the event
which is a first class citizne in the language.
For example in Java, you would use the setOnClickListener
but in Xamarin instead you use Click
event. Here are some of the events available :
Click
- Callback when the view is clickedDrag
- Callback when the view is draggedFocusChange
- Callback when the view changes focusGenericMotion
- Callback for arbitrary gesturesHover
- Callback for hovering over the viewKeyPress
- Callback for pressing a hardware key when view has focusLongClick
- Callback for pressing and holding a viewTouch
- Callback for touching down or up on a view
Button Events
We can use the Click
event to detect when a button is touched as follows :
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.myButton);
button.Click += delegate { button.Text = $"{count++} clicks!"; };
or we can use a lambda as follows :
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.myButton);
button.Click += (object sender, System.EventArgs e) => {
button.Text = $"{count++} clicks!";
};
or we can use a method to handle the click event :
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.myButton);
button.Click += Button_Click;
with the following method defined :
void Button_Click(object sender, System.EventArgs e)
{
((Button)sender).Text = $"{count++} clicks!";
}
This pattern works for any of the view-based event listeners.
Button Events in XML
You can also add the Click
event in the XML but it involves a few steps to get it to work :
- Add reference to the
Mono.Android.Export
- Decorate the method with the
[Java.Interop.Export("MethodName")
In the xml layout, add the onClick
to the button as follows :
<Button
android:onClick="OnClick"
android:id="@+id/myButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
and in the code file :
[Java.Interop.Export("OnClick")]
public void OnClick(View v)
{
Console.WriteLine("Button clicked");
}
Notice we are exporting the Java method so that we can use it our code with .NET.
EditText Common Listeners
In addition to the listeners described above, there are a few other common listeners for input fields in particular.
TextChanged
- Fires each time the text in the field is being changedEditorAction
- Fires when an “action” button on the soft keyboard is pressed
TextChanged Events
This is great for any time you want to have the UI update as the user enters text.
// Fires right before text is changing
etUsername.BeforeTextChanged += (object sender, Android.Text.TextChangedEventArgs e) => {
Console.WriteLine(e.Text);
};
// Fires right as the text is being changed (even supplies the range of text)
etUsername.TextChanged += (object sender, Android.Text.TextChangedEventArgs e) => {
Console.WriteLine(e.Text);
};
// Fires right after the text has changed
etUsername.AfterTextChanged += (object sender, Android.Text.AfterTextChangedEventArgs e) =>
{
Console.WriteLine(e.Editable.ToString());
};
EditorAction Event
Another case is when you want an action to occur once the user has finished typing text with the Soft Keyboard.
First, we need to setup an “action” button for our text field. To setup an “action button” such as a Done button on the soft Keyboard, simply configure your EditText with the following properties:
<EditText
android:inputType="text"
android:singleLine="true"
android:imeOptions="actionDone"
android:id="@+id/etValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<requestFocus />
</EditText>
etUsername.EditorAction += (object sender, TextView.EditorActionEventArgs e) => {
if (e.ActionId == Android.Views.InputMethods.ImeAction.Done) {
var text = etUsername.Text;
}
};
This is often great whenever a user needs to type text and then explicitly have an action performed when they are finished. More actions can be found here
AdapterView Event Listeners
In addition to the standard View listeners, AdapterView
descendants have a few more key event listeners having to do with their items:
ItemClick
- Callback when an item contained is clickedItemLongClick
- Callback when an item contained is clicked and heldItemSelected
- Callback when an item is selected
Troubleshooting: Item Click Not Firing If the item is more complex and does not seem to be properly responding to clicks after setting up the handler, the views inside the item might be drawing the focus. Check out this stackoverflow post and add the property android:descendantFocusability="blocksDescendants"
to the root layout within the template for the item.
References
- http://stackoverflow.com/questions/20197848/xamarin-android-how-to-capture-button-events-defined-in-the-onclick-xml-attribu
- http://developer.android.com/guide/topics/ui/controls/button.html
- http://developer.android.com/reference/android/widget/Button.html
- http://developer.android.com/guide/topics/ui/ui-events.html
- http://developer.android.com/reference/android/view/View.html#setOnClickListener
- setOnEditorActionListener Docs
- addTextChangedListener Docs