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 clicked
  • Drag - Callback when the view is dragged
  • FocusChange - Callback when the view changes focus
  • GenericMotion - Callback for arbitrary gestures
  • Hover - Callback for hovering over the view
  • KeyPress - Callback for pressing a hardware key when view has focus
  • LongClick - Callback for pressing and holding a view
  • Touch - 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 :

  1. Add reference to the Mono.Android.Export
  2. 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 changed
  • EditorAction - 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 clicked
  • ItemLongClick - Callback when an item contained is clicked and held
  • ItemSelected - 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