Xamarin TapGestureRecognizer 在后台点击时触发点击事件

Xamarin TapGestureRecognizer tap event fired on background taps

我遇到了 TapGestureRecognizer 的一些奇怪行为。我有一些简单的 Xamarin 页面,如下所示

<StackLayout>
    <Path
        ClassId="BottomCone"
        Fill="{AppThemeBinding Dark=#333333, Light=#444444}"
        Data="{x:Static local:MainPage.BottomConeGeometry}"
        BackgroundColor="Red"
                
    >
        <Path.GestureRecognizers>
            <TapGestureRecognizer Tapped="BottomConeTapped" />
        </Path.GestureRecognizers>
    </Path>
</StackLayout>

虽然它实际上只是一些简单的闭合形状,但它被 Path 元素淹没了,我在上面有一些点击事件的处理程序。问题是每次我点击路径或其背景时,事件都会触发。当点击发生在路径的背景中时,是否可以不触发点击事件?并触发事件,以防点击事件发生在 Path 元素内。

因此形状具有重叠的“边界”(每个形状周围的矩形)。

一种技术是拥有一组近似于每个形状的矩形。这个概念是让形状本身 InputTransparent,并有一组重叠的隐形盒子来捕捉触摸。

OverlappingShapeButtonsPage.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"
             x:Class="XFSOAnswers.OverlappingShapeButtonsPage">
    <ContentPage.Resources>
        <Style TargetType="BoxView">
            <!-- Uncomment, to see where OnTapped1 boxes are. -->
            <!--<Setter Property="BackgroundColor" Value="Red"/>-->
        </Style>
    </ContentPage.Resources>
    <ContentPage.Content>
        <Grid>

            <AbsoluteLayout InputTransparent="True">
                <Polygon Points="0,0 80,0 0,60" Fill="Green" />
                <Polygon Points="80,0 80,60 0,60" Fill="Pink" />
            </AbsoluteLayout>

            <Grid RowDefinitions="20,20,20" ColumnDefinitions="20,20,20,20"
                  RowSpacing="0" ColumnSpacing="0">
                <Grid.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnTapped2" />
                </Grid.GestureRecognizers>
                <BoxView Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
                    <BoxView.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnTapped1" />
                    </BoxView.GestureRecognizers>
                </BoxView>
                <BoxView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
                    <BoxView.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnTapped1" />
                    </BoxView.GestureRecognizers>
                </BoxView>
                <BoxView Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="1">
                    <BoxView.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnTapped1" />
                    </BoxView.GestureRecognizers>
                </BoxView>
            </Grid>

        </Grid>
    </ContentPage.Content>
</ContentPage>

OverlappingShapeButtonsPage.xaml.cs:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace XFSOAnswers
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class OverlappingShapeButtonsPage : ContentPage
    {
        public OverlappingShapeButtonsPage()
        {
            InitializeComponent();
        }

        /// <summary>
        /// This is called when any of the BoxViews are touched.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnTapped1(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// This is called when the grid is touched anywhere that is not inside one of the BoxViews.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnTapped2(object sender, EventArgs e)
        {

        }
    }
}

用户看到的内容:

红色显示 OnTapped1 的框,近似于绿色三角形:

这相当有效,因为用户倾向于触摸他们感兴趣的形状的中心附近。


您可以通过简单的 (x,y) 数学计算来优化这两个形状之间的边缘。


一般来说,请确保您不会期望用户触摸的精度不切实际。首先,这意味着触摸区域不能太小(小区域超过一个)。

考虑这些(或类似的)准则:Optimal Size and Spacing for Mobile Touch