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.
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.
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
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(); } } }
GestureOverlayView gestureOverlayView = new GestureOverlayView(this); gestureOverlayView.AddOnGesturePerformedListener(this); SetContentView(gestureOverlayView);
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(); }
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.
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 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
3.136.27.75