【问题标题】:Why tap gesture recognizer wont work in absolute layout?为什么点击手势识别器在绝对布局中不起作用?
【发布时间】:2019-10-01 14:30:09
【问题描述】:

使用 Xamarin.Forms 在 Android 上开发一个项目。我正在尝试创建一个包含六个图像按钮的页面,以在应用程序中导航用户。垂直半页,右侧 3 个,左侧 3 个。没有滚动没有其他东西。当我使用绝对布局时,只有屏幕底部的图像有效。其他图像按钮不起作用。如果我只放两张图片,它们就可以工作。

他们在一个网格中。我删除了网格尝试,没有任何改变。

<AbsoluteLayout BackgroundColor="Black"
                        AbsoluteLayout.LayoutBounds="0, 220, 1, 50" AbsoluteLayout.LayoutFlags="XProportional,WidthProportional">
        <AbsoluteLayout AbsoluteLayout.LayoutBounds="9,0,.4,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
            <Image Source="historical"
                            AbsoluteLayout.LayoutBounds="15,.1" AbsoluteLayout.LayoutFlags="YProportional">
                <Image.GestureRecognizers>
                    <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped"/>
                </Image.GestureRecognizers>
            </Image>

        </AbsoluteLayout>
        <AbsoluteLayout AbsoluteLayout.LayoutBounds="9,0,.4,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
            <Image Source="hotel"
                            AbsoluteLayout.LayoutBounds="15,.5" AbsoluteLayout.LayoutFlags="YProportional" >
                <Image.GestureRecognizers>
                    <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped_1"/>
                </Image.GestureRecognizers>
            </Image>

        </AbsoluteLayout>
        <AbsoluteLayout AbsoluteLayout.LayoutBounds="9,0,.4,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
            <Image Source="camp"
                            AbsoluteLayout.LayoutBounds="15,.9" AbsoluteLayout.LayoutFlags="YProportional" >
                <Image.GestureRecognizers>
                    <TapGestureRecognizer
                            Tapped="Camp_Clicked"/>
                </Image.GestureRecognizers>
            </Image>

        </AbsoluteLayout>
        <AbsoluteLayout AbsoluteLayout.LayoutBounds="190,0,.4,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
            <Image Source="food"
                            AbsoluteLayout.LayoutBounds="12,.1" AbsoluteLayout.LayoutFlags="YProportional" >
                <Image.GestureRecognizers>
                    <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped_2"/>
                </Image.GestureRecognizers>
            </Image>


        </AbsoluteLayout>
        <AbsoluteLayout AbsoluteLayout.LayoutBounds="190,0,.4,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
            <Image Source="airport"
                            AbsoluteLayout.LayoutBounds="12,.5" AbsoluteLayout.LayoutFlags="YProportional" >
                <Image.GestureRecognizers>
                    <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped_3"/>
                </Image.GestureRecognizers>
            </Image>

        </AbsoluteLayout>
        <AbsoluteLayout AbsoluteLayout.LayoutBounds="190,0,.4,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
            <Image Source="adventure"
                            AbsoluteLayout.LayoutBounds="12,.9" AbsoluteLayout.LayoutFlags="YProportional" >
                <Image.GestureRecognizers>
                    <TapGestureRecognizer
                            Tapped="Adventure_Clicked"/>
                </Image.GestureRecognizers>
            </Image>

        </AbsoluteLayout>
    </AbsoluteLayout>

这是网格版本。这也有同样的问题。

<Grid>
            <Grid Grid.Column="0" >
                <AbsoluteLayout BackgroundColor="Black"
                        AbsoluteLayout.LayoutBounds="0, 220, 1, 50" AbsoluteLayout.LayoutFlags="XProportional,WidthProportional">
                    <AbsoluteLayout AbsoluteLayout.LayoutBounds="0,0,.9,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
                        <Image Source="historical"
                            AbsoluteLayout.LayoutBounds="15,.1" AbsoluteLayout.LayoutFlags="YProportional">
                            <Image.GestureRecognizers>
                                <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped"/>
                            </Image.GestureRecognizers>
                        </Image>

                    </AbsoluteLayout>
                    <AbsoluteLayout AbsoluteLayout.LayoutBounds="0,0,.9,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
                        <Image Source="hotel"
                            AbsoluteLayout.LayoutBounds="15,.5" AbsoluteLayout.LayoutFlags="YProportional" >
                            <Image.GestureRecognizers>
                                <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped_1"/>
                            </Image.GestureRecognizers>
                        </Image>

                    </AbsoluteLayout>
                    <AbsoluteLayout AbsoluteLayout.LayoutBounds="0,0,.9,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
                        <Image Source="camp"
                            AbsoluteLayout.LayoutBounds="15,.9" AbsoluteLayout.LayoutFlags="YProportional" >
                            <Image.GestureRecognizers>
                                <TapGestureRecognizer
                            Tapped="Camp_Clicked"/>
                            </Image.GestureRecognizers>
                        </Image>

                    </AbsoluteLayout>
                </AbsoluteLayout>




            </Grid>
            <Grid Grid.Column="1">



                <AbsoluteLayout BackgroundColor="Black"
                        AbsoluteLayout.LayoutBounds="0, 220, 1, 50" AbsoluteLayout.LayoutFlags="XProportional,WidthProportional">
                    <AbsoluteLayout AbsoluteLayout.LayoutBounds="0,0,.9,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
                        <Image Source="food"
                            AbsoluteLayout.LayoutBounds="12,.1" AbsoluteLayout.LayoutFlags="YProportional" >
                            <Image.GestureRecognizers>
                                <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped_2"/>
                            </Image.GestureRecognizers>
                        </Image>

                    </AbsoluteLayout>

                        <AbsoluteLayout AbsoluteLayout.LayoutBounds="0,0,.9,.9" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional">
                            <Image Source="airport"
                            AbsoluteLayout.LayoutBounds="5,.5" AbsoluteLayout.LayoutFlags="YProportional" >
                                <Image.GestureRecognizers>
                                    <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped_3"/>
                                </Image.GestureRecognizers>
                            </Image>

                        </AbsoluteLayout>



                </AbsoluteLayout>



            </Grid>
        </Grid>

【问题讨论】:

  • 这是没有工作图像按钮的页面布局。link
  • AbsoluteLayouts 可以重叠视图并防止其他人被窃听。我建议回到 Grid 计划。这也将允许不同大小的视图。你能显示你拥有的网格代码吗?然后我们也许可以看到为什么 Grid 有问题
  • 我添加了网格版本,TaylorD

标签: visual-studio xaml xamarin.forms xamarin.android


【解决方案1】:

为什么点击手势识别器在绝对布局中不起作用?

给每个AbsoluteLayout加个背景色就很容易找出原因了,我加了,看看结果:

只有屏幕底部的图片和其他图片被这两个AbsoluteLayout重叠,所以点击手势识别器不起作用。

解决方案:

要正确使用absolute-layout,您应该阅读document 并了解其工作原理。

在你的代码中,你设置了左边的3个AbsoluteLayoutAbsoluteLayout.LayoutBounds="9,0,.4,.9",第二个参数表示the y (vertical) position of the view's anchor,你都设置了0,所以都是从屏幕顶部开始的,这导致了重叠。

我更改了您的 xaml 代码,我认为这就是您想要实现的目标:

<AbsoluteLayout BackgroundColor="Yellow"
                    AbsoluteLayout.LayoutBounds="0, 220, 1, 50" AbsoluteLayout.LayoutFlags="XProportional,WidthProportional">
    <AbsoluteLayout BackgroundColor="Red" AbsoluteLayout.LayoutBounds="9,0,.4,.3" AbsoluteLayout.LayoutFlags="YProportional,WidthProportional,HeightProportional">
        <Image Source="Images"
                        AbsoluteLayout.LayoutBounds="15,.1" AbsoluteLayout.LayoutFlags="YProportional">
            <Image.GestureRecognizers>
                <TapGestureRecognizer
                        Tapped="TapGestureRecognizer_Tapped"/>
            </Image.GestureRecognizers>
        </Image>

    </AbsoluteLayout>
    <AbsoluteLayout BackgroundColor="Pink" AbsoluteLayout.LayoutBounds="9,.5,.4,.3" AbsoluteLayout.LayoutFlags="YProportional, WidthProportional,HeightProportional">
        <Image Source="Images"
                        AbsoluteLayout.LayoutBounds="15,.5" AbsoluteLayout.LayoutFlags="YProportional" >
            <Image.GestureRecognizers>
                <TapGestureRecognizer
                        Tapped="TapGestureRecognizer_Tapped"/>
            </Image.GestureRecognizers>
        </Image>

    </AbsoluteLayout>

    <AbsoluteLayout BackgroundColor="Green" AbsoluteLayout.LayoutBounds="9,1,.4,.3" AbsoluteLayout.LayoutFlags="YProportional,WidthProportional,HeightProportional">
        <Image Source="Images"
                        AbsoluteLayout.LayoutBounds="15,.9" AbsoluteLayout.LayoutFlags="YProportional" >
            <Image.GestureRecognizers>
                <TapGestureRecognizer
                        Tapped="TapGestureRecognizer_Tapped"/>
            </Image.GestureRecognizers>
        </Image>

    </AbsoluteLayout>

    <AbsoluteLayout BackgroundColor="Gray" AbsoluteLayout.LayoutBounds="190,0,.4,.3" AbsoluteLayout.LayoutFlags="YProportional,WidthProportional,HeightProportional">
        <Image Source="Images"
                        AbsoluteLayout.LayoutBounds="12,.1" AbsoluteLayout.LayoutFlags="YProportional" >
            <Image.GestureRecognizers>
                <TapGestureRecognizer
                        Tapped="TapGestureRecognizer_Tapped"/>
            </Image.GestureRecognizers>
        </Image>


    </AbsoluteLayout>

    <AbsoluteLayout BackgroundColor="Blue" AbsoluteLayout.LayoutBounds="190,0.5,.4,.3" AbsoluteLayout.LayoutFlags="YProportional, WidthProportional,HeightProportional">
        <Image Source="Images"
                        AbsoluteLayout.LayoutBounds="12,.5" AbsoluteLayout.LayoutFlags="YProportional" >
            <Image.GestureRecognizers>
                <TapGestureRecognizer
                        Tapped="TapGestureRecognizer_Tapped"/>
            </Image.GestureRecognizers>
        </Image>

    </AbsoluteLayout>

    <AbsoluteLayout BackgroundColor="Orange" AbsoluteLayout.LayoutBounds="190,1,.4,.3" AbsoluteLayout.LayoutFlags="YProportional, WidthProportional,HeightProportional">
        <Image Source="Images"
                        AbsoluteLayout.LayoutBounds="12,.9" AbsoluteLayout.LayoutFlags="YProportional" >
            <Image.GestureRecognizers>
                <TapGestureRecognizer
                        Tapped="TapGestureRecognizer_Tapped"/>
            </Image.GestureRecognizers>
        </Image>

    </AbsoluteLayout>
</AbsoluteLayout>

结果如下:

另外,我建议您使用Grid 来布局您的图像,它更简单快捷。

【讨论】:

    【解决方案2】:

    我建议将您的 xaml 更改为使用带有行和列定义的 Grid,而不是使用 AbsoluteLayout

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
    
        <Image Source="historical"
               Grid.Row="0"
               Grid.Column="0">
            <Image.GestureRecognizers>
                <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
            </Image.GestureRecognizers>
        </Image>
    
        <!-- Place the rest of your Images with TapGestureRecognizers below -->
        <!-- with the appropriate row/column value for each -->
    </Grid>
    

    这将为您提供 3 行和 2 列来放置您的图像。它可以根据安装应用程序的设备调整大小,并且还应该允许您的 TapGestureRecognizers 被执行。

    仅使用网格和行/列定义以及当前存在的所有绝对布局代码。视图的重叠导致页面顶部的视图无法点击。

    【讨论】:

      【解决方案3】:

      我不确定为什么会发生这种情况,因为您的 XAML 有点令人困惑,但我了解您想要做什么。这基本上是TaylorD所说的。将其更改为 Grid,而不是 AbsoluteLayout

      它将为您完成所有调整大小和定位的工作,并且可能会解决您的问题。正在发生的情况可能是您的一个控件在其他控件之上并且占据了整个屏幕,所以当您点击时,您点击的是这个控件,而不是您想要的那个。

      只需将其更改为 Grid 即可解决您的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-27
        相关资源
        最近更新 更多