Creating your own gestures

In the past three recipes of this chapter we learned how to use the camera and how to create animations to enhance the user experience. However, the animations are passive in a sense that your user can only watch them. In this recipe, we will try to engage our future users by proposing custom gestures for our application.

Getting ready

This recipe can only be achieved with the use of a physical Android phone. That said, create a new solution named CustomGesture in Xamarin Studio.

How to do it...

  1. Go to the Google Play store and install the Gesture tool app created by davemac: https://play.google.com/store/apps/details?id=com.davemac327.gesture.tool&hl=en
  2. Create some gestures with the tool, as shown in the following screenshot:
    How to do it...
  3. Notice the path where the gestures are saved:
    How to do it...
  4. Extract the gesture binaries created by the Gesture tool and import them in the Ressource/raw directory of your project using the following command:
    adb pull /storage/sdcard0/gestures PathToCustomeGesture/Resources/raw
    
  5. In your MainActivity class' OnCreate() function, load the gesture files into a gesture library:
    private Android.Gestures.GestureLibrary _myGestures;
    
      protected override void OnCreate (Bundle bundle) {
        base.OnCreate (bundle);
        _myGestures = Android.Gestures.GestureLibraries.FromRawResource(this, Resource.Raw.gestures);
        if (!_myGestures.Load()) {
          // The library didn't load, so close the activity.
          Finish();
        }
      }
    }
  6. Just after the previous snippet, add a gesture overlay to your activity:
    GestureOverlayView gestureOverlayView = new GestureOverlayView(this);
    gestureOverlayView.AddOnGesturePerformedListener(this);
    SetContentView(gestureOverlayView); 
  7. Add a GestureOverlayViewOnGesturePerformed() function to your MainActivity class. You will also have to import System.Linq, as we did in earlier chapters:
    private void GestureOverlayViewOnGesturePerformed(object sender, GestureOverlayView.GesturePerformedEventArgs gesturePerformedEventArgs) {
    
      System.Collections.Generic.IEnumerable<Prediction> predictions = from p in _myGestures.Recognize (gesturePerformedEventArgs.Gesture)
      orderby p.Score descending
      where p.Score > 1.0
      select p;
      Prediction prediction = predictions.FirstOrDefault(); 
    
      if (prediction == null) {
        Toast.MakeText(this, "No Match", ToastLength.Short).Show();
        return;
      }
    
      Toast.MakeText(this, prediction.Name, ToastLength.Short).Show(); 
    }
  8. Run your application and try some gestures. If the current gesture is recognized, then a toast with the name of the gesture will be displayed. Otherwise, a toast containing No Match will appear.

How it works...

First of all, for the first time in this book, we use raw resources and use one of them to bootstrap a gesture library:

_myGestures = Android.Gestures.GestureLibraries.FromRawResource(this, Resource.Raw.gestures);

Raw resources are arbitrary files that are saved in their raw form. To open these resources with a raw InputStream, we can call the Resources.openRawResource() method with the resource Resource.Raw.gestures as a resource ID. This mechanism is provided by the GestureLibraries and the convenient FromRawResource() method. This statement returns a GestureLibrary object initialized with our raw file and it's responsible for maintaining gesture examples—created with the gesture tool we download as a first step—and makes predictions on a new gesture.

We used the prediction mechanism provided by the GestureLibrary in the GestureOverlayViewOnGesturePerformed() method:

System.Collections.Generic.IEnumerable<Prediction> predictions = from p in _myGestures.Recognize(gesturePerformedEventArgs.Gesture)
orderby p.Score descending
where p.Score > 1.0
select p;

In this snippet, we ask our GestureLibrary to recognize the gesture that the user just made and order our custom gesture by score, using the Linq syntax described in Chapter 5, Using On-Phone Data. The closest the gesture is to one of our custom gestures, the higher the score. Finally we selected the first Gesture in the collection of predictions ranked by score using:

Prediction prediction = predictions.FirstOrDefault();

The documentation about how the score is actually computed is rather scarce, but my best guess is a Euclidian distance between each pixel of the custom gesture and the pixels of the draw gesture, with some vector transformation in order to take into account the different sizes of screens and orientations.

There's more...

In this recipe we learned how to create our own gesture to improve the user experience, however, the Android SDK and therefore Xamarin, allow us to use some pre-configured gestures such as OnTouch, OnLongPress, and so on.

Detecting those preconfigured events is fairly simple. First you have to create a class extending the IOnGestureListener interface. Then, in the OnCreate() method of your MainActivity class, you have to create a gesture detector using your implementation of IOnGestureListener, as follows:

GestureOverlayView.IOnGestureListener myListener = new MyImplementationOfIGestureListener();
_gestureDetector = new GestureDetector (this, myListener);

Finally, in your MainActivity class, implement, for example, the following method:

public override bool OnTouchEvent(MotionEvent e) {
  //Some business here
}

This will be triggered when an OnTouch event happens.

See also

See also Chapter 10, Taking Advantage of the Android Platform—to build even more advanced applications, and the following online resources to deepen your understanding of custom gestures:

http://developer.android.com/training/gestures/detector.html

http://developer.android.com/training/gestures/multi.html

https://play.google.com/store/apps/details?id=com.davemac327.gesture.tool

..................Content has been hidden....................

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