2

I'm using Xamarin to build a Google Glass application, and haven't been able to get the GestureDetector to fire any OnGesture events. Here is what I've tried so far:

In my Activity:

    using Gesture = Android.Glass.Touchpad.Gesture;
    using GestureDetector = Android.Glass.Touchpad.GestureDetector;

    private GestureDetector _gestureDetector;

    protected override void OnCreate(Bundle bundle)
    {
      base.OnCreate(bundle);

      this._gestureDetector = new GestureDetector(this);
      this._gestureDetector.SetBaseListener(new GestureListener());
    }

    public override bool OnGenericMotionEvent(MotionEvent e)
    {
        if (this._gestureDetector != null)
        {
            return this._gestureDetector.OnMotionEvent(e);
        }

        return false;
    }

The IBaseListener implementation:

class GestureListener : GestureDetector.IBaseListener
{
    public bool OnGesture(Gesture gesture)
    {

        if (gesture == Gesture.SwipeRight)
        {
            // do something on right (forward) swipe
            return true;
        }
        else if (gesture == Gesture.SwipeLeft)
        {
            // do something on left (backwards) swipe
            return true;
        }
        return false;
    }

    public void Dispose()
    {

    }

    public IntPtr Handle { get; set; }
}

I tried setting a breakpoint just inside the OnGesture method, but it is never triggered. Is there something missing from my IBaseListener implementation?

poupou
  • 43,413
  • 6
  • 77
  • 174
Eric Levine
  • 13,536
  • 5
  • 49
  • 49

1 Answers1

3

It turns out that I needed to make my listener implementation extend Java.Lang.Object, as mentioned in the Xamarin article about Android Callable Wrappers. Below is a fully working sample Activity.

using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Gesture = Android.Glass.Touchpad.Gesture;
using GestureDetector = Android.Glass.Touchpad.GestureDetector;


namespace GlassGestureTest
{
    using Android.Util;

    using Java.Util.Logging;

    [Activity(Label = "GlassGestureTest", MainLauncher = true, Icon = "@drawable/icon")]
    public class Activity1 : Activity
    {

        private GestureDetector _gestureDetector;

        int count = 1;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // 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 = string.Format("{0} clicks!", count++); };

            this._gestureDetector = new GestureDetector(this);
            this._gestureDetector.SetBaseListener(new GestureListener());
        }

        public override bool OnGenericMotionEvent(MotionEvent e)
        {
            if (this._gestureDetector != null)
            {
                return this._gestureDetector.OnMotionEvent(e);  
            }

            return false;
        }
    }

    // Note - the key part here is to extend Java.Lang.Object in order to properly setup
    // the IntPtr field and Dispose method required by IBaseListener
    public class GestureListener : Java.Lang.Object, GestureDetector.IBaseListener
    {
        public bool OnGesture(Gesture gesture)
        {
            if (gesture == Gesture.SwipeRight)
            {
                // do something on right (forward) swipe
                return true;
            }
            else if (gesture == Gesture.SwipeLeft)
            {
                // do something on left (backwards) swipe
                return true;
            }
            else if (gesture == Gesture.SwipeDown)
            {
                // do something on the down swipe
                return true;
            }
            else if (gesture == Gesture.SwipeUp)
            {
                // do something on the up swipe
                return true;
            }

            return false;
        }
    }
}
Eric Levine
  • 13,536
  • 5
  • 49
  • 49
  • This is great; thanks for sharing. I was wondering how does one get a handle to the card and then udpate that? For example if i want to update the card when Tapped (Gesture == Tap) - any ideas on how to to that? Thanks. – bahree Mar 27 '14 at 11:24
  • @bahree If you post a question with some more details I can take a look. – Eric Levine Mar 27 '14 at 17:38