On the Nexus 9 and Nexus 7, the values returned by MotionEvent.GetX() and MotionEvent.GetY() are larger than they should be. On other devices, it's fine. I've gotten this down to a reproducible bit of code.
Here's the code for a custom view. Whenever the renderer calls the MoveBox() method, it moves the box to the location of the tap.
public class CustomView : AbsoluteLayout
{
BoxView bv;
public CustomView()
{
this.HorizontalOptions = LayoutOptions.FillAndExpand;
this.VerticalOptions = LayoutOptions.FillAndExpand;
this.BackgroundColor = Color.Blue;
bv = new BoxView();
bv.Color = Color.Pink;
Children.Add(bv);
AbsoluteLayout.SetLayoutBounds(bv, new Rectangle(0, 0, 40, 40));
}
public void MoveBox(double x, double y)
{
AbsoluteLayout.SetLayoutBounds(bv, new Rectangle(x, y, 40, 40));
}
}
public class App : Application
{
public App()
{
// The root page of your application
MainPage = new ContentPage
{
Content = new StackLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = {
new CustomView {
}
}
}
};
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
And here's the code for the renderer:
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Xamarin.Forms.Platform.Android;
[assembly: Xamarin.Forms.ExportRenderer(typeof(Android_GestureRecognizer.CustomView), typeof(Android_GestureRecognizer.Droid.CustomViewRenderer))]
namespace Android_GestureRecognizer.Droid
{
public class CustomViewRenderer : VisualElementRenderer<Android_GestureRecognizer.CustomView>, GestureDetector.IOnGestureListener
{
private GestureDetector _g;
public CustomViewRenderer()
{
_g = new GestureDetector(this);
}
private CustomView theview // TODO
{
get
{
return Element;
}
}
public bool OnSingleTapUp(MotionEvent ev)
{
//Tell the view to move the BoxView.
theview.MoveBox(ev.GetX(), ev.GetY());
return true;
}
public void OnLongPress(MotionEvent ev)
{
}
public void OnShowPress(MotionEvent ev)
{
}
public bool OnFling(MotionEvent ev1, MotionEvent ev2, float vx, float vy)
{
return false;
}
public bool OnDown(MotionEvent ev)
{
return false;
}
public bool OnScroll(MotionEvent ev1, MotionEvent ev2, float dx, float dy)
{
return false;
}
public override bool OnTouchEvent(MotionEvent e)
{
bool b = _g.OnTouchEvent(e);
if (b)
{
return true;
}
else
{
return base.OnTouchEvent(e);
}
}
}
[Activity(Label = "Android_GestureRecognizer", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}