Responding to simple touches

One of the primary means for the user to interact with the device is through touch. Often, this is the only way as there is no keyboard or mouse, and other methods might be unavailable or undesirable.

How to do it...

All views provide access to the two most common forms of touch input: single taps and long presses. We respond to these events using either listeners or event handlers:

  1. We respond to taps using the Click event:
    view.Click += (sender, e) => {
      // the user tapped the view
    };
  2. In the same way, we respond to long presses using the LongClick event. To prevent the Click event from also being triggered, we ensure that the Handled property of the EventArgs is set to true:
    view.LongClick += (sender, e) => {
      // the user long-pressed on the view
      e.Handled = true;
    };

Both the Click and LongClick events can also be subscribed to using listeners:

  1. To use a listener with the Click event, we ensure that we implement the View.IOnClickListener interface:
    public class MyView : View, View.IOnClickListener {
      public void OnClick(View view) {
        // the user tapped the view
      }
    }
  2. To subscribe using the listener, we make use of the SetOnClickListener() method:
    SetOnClickListener(this);
  3. Similarly, the LongClick events can also be subscribed to using listeners. To do this, we implement the View.IOnLongClickListener interface:
    public class MyView : View, View.IOnLongClickListener {
      public bool OnLongClick(View view) {
        // the user long-pressed the view
        return true;
      }
    }
  4. Again, we set the listener using the SetOnLongClickListener() method:
    SetOnLongClickListener(this);

How it works...

There are many ways to interact with apps running on a device. One of the most common ways is touch. Most Android smartphones are built with large, touchscreens which are the primary source of input.

Touch input can range from simple, single taps all the way to multifinger gestures. The simplest and most common are single taps and longpresses. Both forms are very easy to implement, requiring only logic to be attached to the Click event, for single taps, and the LongClick event, for longpress gestures.

Both events will fire as soon as the user completes the touch, but in the case of a long-press, we have to ensure that we let the event system know that we are handling a longpress instead of a single tap.

Note

A long-press is just a tap, but with a longer contact duration.

We let the system know that we are handling the long-press by setting the value of the Handled property on the LongClickEventArgs parameter of the LongClick event to true. If we do not do this, the Click event will also be raised, possibly resulting in unexpected behavior.

Both the Click and LongClick events can also be handled using Java-style listeners. The listener interface for the Click event is View.IOnClickListener and View.IOnLongClickListener for the LongClick event. Instances of classes implementing the interfaces are passed to the SetOnClickListener() and SetOnLongClickListener() methods.

Because the events actually use the listeners under the covers, attaching a handler to the event will disconnect the listeners. Also, assigning a listener to the view will detach the events. As a result, only one form of handler can be used at a time.

Note

Either the C#-style events or the Java-style listeners can be used, but not both at the same time.

There's more...

Sometimes, we need more advanced touch events, such as the number of fingers on the screen and their position on the screen. We get all the touch data by overriding the OnTouchEvent() method and accessing the MotionEvent argument:

public class MyView : View {
  public override bool OnTouchEvent(MotionEvent e) {
    return base.OnTouchEvent(e);
  }
}

Every time a touch event is triggered, we can access the data related to the touch using the MotionEvent argument. This instance contains data such as the number of fingers touching the screen, in the PointerCount property, and the location of each finger, through the GetX() and GetY() methods. We use the ActionMasked property to determine what raised the event. Possible reasons for touch events could be that a finger was either added, removed, or moved over the screen.

We can use this data to interpret gestures such as zoom, rotate, or drag. Here, we store all the fingers in a dictionary, along with their position on the screen:

var pointerIndex = e.ActionIndex;
var pointerId = e.GetPointerId(pointerIndex);
switch (e.ActionMasked) {
  case MotionEventActions.Down:
  case MotionEventActions.PointerDown:
    pointers[pointerId] = new PointF(e.GetX(pointerIndex), e.GetY(pointerIndex));
  break;
  case MotionEventActions.Move:
  for (int i = 0; i < e.PointerCount; i++) {
    var id = e.GetPointerId(i);
    pointers[id] = new PointF(e.GetX(i), e.GetY(i));
  }
  break;
  case MotionEventActions.Up:
  case MotionEventActions.PointerUp:
  case MotionEventActions.Cancel:
    pointers.Remove(id);
  break;
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.106.100