Xamarin:如何获取光标/触摸坐标(位置X和Y)? [英] Xamarin: how to get cursor/touch coordinates (position X and Y)?

查看:404
本文介绍了Xamarin:如何获取光标/触摸坐标(位置X和Y)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介

我正在创建我的第一个Xamarin应用程序(它将首先针对UWP,然后针对Android,最后可能针对iOS).

基本上,该应用程序应该检测到多个手指,并且圆圈将在每个手指上弹出并跟随它们.

我的应用

首先,我认为Xamarin无法对UI和图形进行编码,因此我开始了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位置停留,以画出我的椭圆. 如您所见,我采用了不同的方式:TapGestureRecognizerPanGestureRecognizer ...

但是我无法得到那些齿龈.

我找到了 MR.Gestures API,但已获得每个应用名称的许可./p>

问题

所以,我要问有经验的人:

  • Xamarin是否提供触摸位置/手势API?
  • 做MR.Gestures是 处理触摸的最佳解决方案?
  • 是否还有其他触摸共享代码 API?

或者简单地说,我如何获得Xamarin的所有接触点的坐标??

谢谢

PS:我发现解决方案

Xamarin是否提供触摸位置/手势API?

不幸的是,不!正如您提到的,使用Xamarin唯一可以做的就是使用TapGestureRecognizerPinchGestureRecognizerPanGestureRecognizer类,仅此而已.他们都不会给你x/y坐标.

MR.Gestures是处理触摸的最佳解决方案吗?

我遇到了相同类型的问题.如果您不想重新发明轮子,那么绝对应该使用外部API.

手势先生做得很好.不幸的是,我还没有听说过任何免费的API.正如您所提到的,它是每个许可的应用程序:(

或者简单地说,我如何获得所有接触点的坐标 Xamarin?

您应该为每个平台(或您的情况下的UWP)实现自定义渲染器.这就是手势先生在幕后为您做的.如果您不想自己实现此功能,那么当前唯一的选择就是使用外部API.

也许有一天Xamarin会开箱即用地提供这种API……让我们保持联系!

希望这会有所帮助!

Introduction

I am creating my first Xamarin app (that will target UWP first, then Android, finally maybe iOS).

Basically, the app should detect multiple fingers and circles will pop over each finger and follow them.

My app

First I thought that UI and graphics couldn't be coded with Xamarin so I started UWP code :

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>

As you can see, I can get the X and Y position of the cursor, BUT my ellipse doesn't display. So I noticed that Xamarin xaml won instead of my UWP xaml.

So I tried again with Xamarin. I looked for shared code graphics API, I found SkiaSharp. And my ellipse appear in the Xamarin code :

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>

Finally, it rests only the X and Y position for each touched point to draw my ellipses on. As you can see, I looked different ways: TapGestureRecognizer, PanGestureRecognizer ...

But I couldn't get those coordonates.

I found MR.Gestures API, but it's licensed per app name.

Questions

So, I am asking experimented people :

  • Do Xamarin provides touch position/gesture API ?
  • Do MR.Gestures is the best solution to handle touch ?
  • Is there other touch shared code APIs ?

Or simply, how can I get the coordonates of all touched points with Xamarin ?

Thanks

PS: I find this article while writting this Stack, reading ...

解决方案

Do Xamarin provides touch position/gesture API ?

Unfortunatly, no! The only thing you can do with Xamarin is using the TapGestureRecognizer, PinchGestureRecognizer or PanGestureRecognizer class, as you mentionned, but that's all. None of them will give you x/y coordinates.

Do MR.Gestures is the best solution to handle touch ?

I came across a same type of issue. If you don't want to reinvent the wheel, you should definitely go for an external API.

Mr.Gestures does the job pretty good. Unfortunatly, I haven't heard of any free API. As you mentionned, it's per app licenced :(

Or simply, how can I get the coordonates of all touched points with Xamarin ?

You should implement custom renderers for each platform (or UWP in your case). That's what Mr.Gestures does for you behind the scenes. If you don't want to implement this yourself, currently your only option is to use an external API.

Maybe one day Xamarin will provide this kind of API out of the box... Let's keep finger crossed!

Hope this helps!

这篇关于Xamarin:如何获取光标/触摸坐标(位置X和Y)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆