Xamarin:如何获取 cursor/touch 坐标(位置 X 和 Y)?
Xamarin: how to get cursor/touch coordinates (position X and Y)?
简介
我正在创建我的第一个 Xamarin 应用程序(它将首先针对 UWP,然后 Android,最后可能 iOS)。
基本上,应用程序应该检测到多个手指,圆圈会在每个手指上弹出并跟随它们。
我的应用
首先我认为 UI 和图形不能用 Xamarin 编码所以我开始 UWP 代码 :
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Windows.Input;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.Input;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
using Windows.UI.Input;
using Windows.UI.Xaml.Shapes;
using Windows.UI;
namespace App1.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
LoadApplication(new App1.App());
}
private async void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
Debug.WriteLine(e.Pointer.PointerDeviceType + " " + sender + " " + e);
Point pointerPos = e.GetCurrentPoint(rootPanel).Position;
Debug.WriteLine(pointerPos.X + " " + pointerPos.Y);
Ellipse ellipse1 = new Ellipse();
ellipse1.Fill = new SolidColorBrush(Colors.SteelBlue);
ellipse1.Width = 100;
ellipse1.Height = 100;
//ellipse1.Margin.Left = pointerPos.X + 50;
//ellipse1.Margin.Top = pointerPos.Y + 50;
rootPanel.Children.Add(ellipse1);
Debug.WriteLine(rootPanel.Children.Count);
switch (e.Pointer.PointerDeviceType)
{
case PointerDeviceType.Touch:
break;
case PointerDeviceType.Pen:
break;
case PointerDeviceType.Mouse:
ContentDialog noMouseAvaliableDialog = new ContentDialog()
{
Title = "Erreur de méthode d'entrée",
Content = "Il est impossible de savoir qui va jouer en premier aver un joueur :(\n Veuillez essayer avec le clavier.",
PrimaryButtonText = "OK chef"
};
await noMouseAvaliableDialog.ShowAsync();
break;
default:
break;
}
Debug.WriteLine("-------------------------");
}
}
}
MainPage.xaml
<forms:WindowsPage
x:Class="App1.UWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:forms="using:Xamarin.Forms.Platform.UWP"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
PointerPressed="OnPointerPressed">
<RelativePanel
Name="rootPanel"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</RelativePanel>
</forms:WindowsPage>
如您所见,我可以获取光标的 X 和 Y 位置,但我的椭圆不显示。
所以我注意到 Xamarin xaml 赢了而不是我的 UWP xaml.
所以我再次尝试使用 Xamarin。
我寻找共享代码图形API,我找到了SkiaSharp。
我的椭圆出现在 Xamarin 代码中:
MainPage.xaml.cs
using SkiaSharp;
using SkiaSharp.Views.Forms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace App1
{
public partial class MainPage : ContentPage
{
private static SKCanvas canvas;
public MainPage()
{
InitializeComponent();
}
private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
canvas = e.Surface.Canvas;
}
private void onTapGestureRecognizerTapped(object sender, EventArgs e)
{
Debug.WriteLine("Tapped !!!!!");
//((TappedEventArgs) e).
}
/*private void onPanUpdated(object sender, PanUpdatedEventArgs e)
{
Debug.WriteLine("Panned !!!!!" + e.TotalX + " " + e.TotalY);
}*/
internal void drawCircleOnCanvas(Point pointerPos, int radius)
{
Debug.WriteLine(pointerPos.X + " " + pointerPos.Y);
SKPaint circleFill = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.Fill,
Color = SKColors.AliceBlue
};
canvas.DrawCircle(((float) pointerPos.X - 50), ((float) pointerPos.Y - 50), radius, circleFill);
}
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage"
xmlns:views="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms">
<Label Text="Ooooh, you touch my tralala"
VerticalOptions="Center"
HorizontalOptions="Center" />
<!--<relativelayout
x:Name="rootPanel"
backgroundcolor="lime"
horizontaloptions="fill"
verticaloptions="fill">
</relativelayout>-->
<Grid>
<views:SKCanvasView PaintSurface="OnPainting"/>
<Grid.GestureRecognizers>
<TapGestureRecognizer
Tapped="onTapGestureRecognizerTapped"
NumberOfTapsRequired="1"/>
<!--<PanGestureRecognizer PanUpdated="onPanUpdated"/> -->
</Grid.GestureRecognizers>
</Grid>
</ContentPage>
最后,它只保留每个触摸点的 X 和 Y 位置来绘制我的椭圆。
如您所见,我查看了不同的方式:TapGestureRecognizer
、PanGestureRecognizer
...
但是我找不到那些坐标。
我找到了 MR.Gestures API,但它的许可是 per app name。
问题
所以,我问实验的人:
- Xamarin 是否提供触摸 position/gesture API ?
- 做 MR.Gestures 是
处理触摸的最佳解决方案?
- 是否有其他触摸共享代码
APIs ?
或者简单地说,如何使用 Xamarin 获取所有触摸点的坐标?
谢谢
PS:我发现 this article 在编写此 Stack 时,正在阅读 ...
Do Xamarin provides touch position/gesture API ?
不幸的是,没有!您可以使用 Xamarin 做的唯一事情就是使用 TapGestureRecognizer
、PinchGestureRecognizer
或 PanGestureRecognizer
class,如您所提到的,仅此而已。 None 个会给你 x/y 坐标。
Do MR.Gestures is the best solution to handle touch ?
我遇到了相同类型的问题。如果你不想重新发明轮子,你绝对应该选择外部 API。
Mr.Gestures 做得很好。不幸的是,我还没有听说过任何免费的 API。正如您提到的,它是每个应用程序许可的:(
Or simply, how can I get the coordonates of all touched points with
Xamarin ?
您应该为每个平台(或您的情况下的 UWP)实现自定义渲染器。这就是 Mr.Gestures 在幕后为您所做的。如果您不想自己实现,目前您唯一的选择是使用外部 API.
也许有一天 Xamarin 会提供这种开箱即用的 API...让我们祈祷吧!
希望对您有所帮助!
晚了,但如果你使用 Skia,你可以添加这个 Nuget:
https://github.com/OndrejKunc/SkiaScene
您将能够跟踪您在场景中的触摸位置。
简介
我正在创建我的第一个 Xamarin 应用程序(它将首先针对 UWP,然后 Android,最后可能 iOS)。
基本上,应用程序应该检测到多个手指,圆圈会在每个手指上弹出并跟随它们。
我的应用
首先我认为 UI 和图形不能用 Xamarin 编码所以我开始 UWP 代码 :
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Windows.Input;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.Input;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
using Windows.UI.Input;
using Windows.UI.Xaml.Shapes;
using Windows.UI;
namespace App1.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
LoadApplication(new App1.App());
}
private async void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
Debug.WriteLine(e.Pointer.PointerDeviceType + " " + sender + " " + e);
Point pointerPos = e.GetCurrentPoint(rootPanel).Position;
Debug.WriteLine(pointerPos.X + " " + pointerPos.Y);
Ellipse ellipse1 = new Ellipse();
ellipse1.Fill = new SolidColorBrush(Colors.SteelBlue);
ellipse1.Width = 100;
ellipse1.Height = 100;
//ellipse1.Margin.Left = pointerPos.X + 50;
//ellipse1.Margin.Top = pointerPos.Y + 50;
rootPanel.Children.Add(ellipse1);
Debug.WriteLine(rootPanel.Children.Count);
switch (e.Pointer.PointerDeviceType)
{
case PointerDeviceType.Touch:
break;
case PointerDeviceType.Pen:
break;
case PointerDeviceType.Mouse:
ContentDialog noMouseAvaliableDialog = new ContentDialog()
{
Title = "Erreur de méthode d'entrée",
Content = "Il est impossible de savoir qui va jouer en premier aver un joueur :(\n Veuillez essayer avec le clavier.",
PrimaryButtonText = "OK chef"
};
await noMouseAvaliableDialog.ShowAsync();
break;
default:
break;
}
Debug.WriteLine("-------------------------");
}
}
}
MainPage.xaml
<forms:WindowsPage
x:Class="App1.UWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:forms="using:Xamarin.Forms.Platform.UWP"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
PointerPressed="OnPointerPressed">
<RelativePanel
Name="rootPanel"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</RelativePanel>
</forms:WindowsPage>
如您所见,我可以获取光标的 X 和 Y 位置,但我的椭圆不显示。 所以我注意到 Xamarin xaml 赢了而不是我的 UWP xaml.
所以我再次尝试使用 Xamarin。 我寻找共享代码图形API,我找到了SkiaSharp。 我的椭圆出现在 Xamarin 代码中:
MainPage.xaml.cs
using SkiaSharp;
using SkiaSharp.Views.Forms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace App1
{
public partial class MainPage : ContentPage
{
private static SKCanvas canvas;
public MainPage()
{
InitializeComponent();
}
private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
canvas = e.Surface.Canvas;
}
private void onTapGestureRecognizerTapped(object sender, EventArgs e)
{
Debug.WriteLine("Tapped !!!!!");
//((TappedEventArgs) e).
}
/*private void onPanUpdated(object sender, PanUpdatedEventArgs e)
{
Debug.WriteLine("Panned !!!!!" + e.TotalX + " " + e.TotalY);
}*/
internal void drawCircleOnCanvas(Point pointerPos, int radius)
{
Debug.WriteLine(pointerPos.X + " " + pointerPos.Y);
SKPaint circleFill = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.Fill,
Color = SKColors.AliceBlue
};
canvas.DrawCircle(((float) pointerPos.X - 50), ((float) pointerPos.Y - 50), radius, circleFill);
}
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage"
xmlns:views="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms">
<Label Text="Ooooh, you touch my tralala"
VerticalOptions="Center"
HorizontalOptions="Center" />
<!--<relativelayout
x:Name="rootPanel"
backgroundcolor="lime"
horizontaloptions="fill"
verticaloptions="fill">
</relativelayout>-->
<Grid>
<views:SKCanvasView PaintSurface="OnPainting"/>
<Grid.GestureRecognizers>
<TapGestureRecognizer
Tapped="onTapGestureRecognizerTapped"
NumberOfTapsRequired="1"/>
<!--<PanGestureRecognizer PanUpdated="onPanUpdated"/> -->
</Grid.GestureRecognizers>
</Grid>
</ContentPage>
最后,它只保留每个触摸点的 X 和 Y 位置来绘制我的椭圆。
如您所见,我查看了不同的方式:TapGestureRecognizer
、PanGestureRecognizer
...
但是我找不到那些坐标。
我找到了 MR.Gestures API,但它的许可是 per app name。
问题
所以,我问实验的人:
- Xamarin 是否提供触摸 position/gesture API ?
- 做 MR.Gestures 是 处理触摸的最佳解决方案?
- 是否有其他触摸共享代码 APIs ?
或者简单地说,如何使用 Xamarin 获取所有触摸点的坐标?
谢谢
PS:我发现 this article 在编写此 Stack 时,正在阅读 ...
Do Xamarin provides touch position/gesture API ?
不幸的是,没有!您可以使用 Xamarin 做的唯一事情就是使用 TapGestureRecognizer
、PinchGestureRecognizer
或 PanGestureRecognizer
class,如您所提到的,仅此而已。 None 个会给你 x/y 坐标。
Do MR.Gestures is the best solution to handle touch ?
我遇到了相同类型的问题。如果你不想重新发明轮子,你绝对应该选择外部 API。
Mr.Gestures 做得很好。不幸的是,我还没有听说过任何免费的 API。正如您提到的,它是每个应用程序许可的:(
Or simply, how can I get the coordonates of all touched points with Xamarin ?
您应该为每个平台(或您的情况下的 UWP)实现自定义渲染器。这就是 Mr.Gestures 在幕后为您所做的。如果您不想自己实现,目前您唯一的选择是使用外部 API.
也许有一天 Xamarin 会提供这种开箱即用的 API...让我们祈祷吧!
希望对您有所帮助!
晚了,但如果你使用 Skia,你可以添加这个 Nuget:
https://github.com/OndrejKunc/SkiaScene
您将能够跟踪您在场景中的触摸位置。