You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI SwipeGestureRecognizer在Android无触发但iOS正常求助

问题:Android模拟器中SwipeGestureRecognizer无法触发,iOS正常

我用Mac VS Code + .NET MAUI 8.0.403开发的应用已上架PlayStore和AppStore,现在遇到一个手势问题:

  • 页面用AbsoluteLayout承载CollectionView,用户滚动阅读文本,期望通过左右滑动切换到下一段
  • iOS模拟器中左右滑动能正常触发OnLeftSwipped和OnRightSwipped事件,段落切换正常
  • Android模拟器中滑动完全不会触发事件处理程序,无任何响应

页面结构:顶部Shell.TitleView放置了设置按钮,点击后通过AbsoluteLayout在底部显示菜单栏。对应的XAML代码如下:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels="clr-namespace:MachainReadingBible.ViewModels"
             xmlns:models="clr-namespace:MachainReadingBible.Models"
             xmlns:local="clr-namespace:MachainReadingBible.Resources.Strings"
             xmlns:skia="clr-namespace:SkiaSharp.Views.Maui.Controls;assembly=SkiaSharp.Views.Maui.Controls"
             x:Class="MachainReadingBible.Views.BibleTextPage"
             x:DataType="viewModels:BibleTextPageViewModel">

    <!-- Shell Title -->
    <Shell.TitleView>
        <Grid ColumnDefinitions="*, Auto, *"
              VerticalOptions="Center">
            <Label Grid.Column="1"
                   x:Name="TitleLabel"
                   HorizontalOptions="Center"
                   VerticalOptions="Center"
                   WidthRequest="200"
                   Style="{StaticResource TitleTextStyle}"
                   Margin="0,0,50,0"/>
            <skia:SKCanvasView Grid.Column="2"
                               PaintSurface="OnPaintSurface"
                               VerticalOptions="Center"
                               HorizontalOptions="End"
                               Margin="20,0,20,0"
                               WidthRequest="40"
                               HeightRequest="20"
                               BackgroundColor="Transparent">
                <skia:SKCanvasView.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnSettingsClicked"/>
                </skia:SKCanvasView.GestureRecognizers>
            </skia:SKCanvasView>
        </Grid>
    </Shell.TitleView>

    <!-- AbsoluteLayout for MenuBar in Bottom -->
    <AbsoluteLayout VerticalOptions="Fill"
                    HorizontalOptions="Fill"
                    AbsoluteLayout.LayoutBounds="0,0,1,1"
                    AbsoluteLayout.LayoutFlags="All">
        <!-- Swipe Event  -->
        <AbsoluteLayout.GestureRecognizers>
            <SwipeGestureRecognizer Direction="Left"
                                    Swiped="OnLeftSwipped"/>
            <SwipeGestureRecognizer Direction="Right"
                                    Swiped="OnRightSwipped"/>
        </AbsoluteLayout.GestureRecognizers>
        <!-- <AbsoluteLayout.GestureRecognizers InputTransparent="False">
            <PanGestureRecognizer PanUpdated="OnPanUpdated"/>
        </AbsoluteLayout.GestureRecognizers> -->

        <Grid RowDefinitions="Auto, *, Auto"
              VerticalOptions="Fill"
              HorizontalOptions="Fill"
              AbsoluteLayout.LayoutBounds="0,0,1,1"
              AbsoluteLayout.LayoutFlags="All">
            <Grid Grid.Row="0"
                  ColumnDefinitions="*, Auto, *"
                  VerticalOptions="Center">
                <BoxView Grid.Column="0"
                         WidthRequest="0"/>
                <Label Grid.Column="1"
                       Text="{Binding Title} "
                       Style="{StaticResource TitleTextStyle}"
                       VerticalOptions="Center"
                       HorizontalOptions="Center"
                       Margin="0,0,0,10"/>
            </Grid>

            <!-- Bible Text output -->
            <CollectionView x:Name="collectionView"
                            Grid.Row="1"
                            ItemsSource="{Binding Verses}"
                            ItemsLayout="VerticalList"
                            VerticalOptions="Fill"
                            HorizontalOptions="Fill">
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="models:VerseDto">
                        <Grid ColumnDefinitions="Auto, *"
                              Padding="0,0,0,10"
                              ColumnSpacing="0">
                            <Label Grid.Column="0"
                                   Text="{Binding VerseNo}"
                                   Style="{StaticResource BibleTextStyle}"
                                   VerticalOptions="Start"
                                   HorizontalTextAlignment="Center"
                                   TranslationY="-3"/>
                            <Label Grid.Column="1"
                                   Text="{Binding Text}"
                                   Style="{StaticResource BibleTextStyle}"
                                   LineBreakMode="CharacterWrap"
                                   VerticalOptions="Center"
                                   HorizontalOptions="Fill"
                                   HorizontalTextAlignment="Start"/>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </Grid>

        <!-- using AbsoluteLayout for MenuBar Display -->
        <Grid x:Name="MenuBar"
              HeightRequest="50"
              IsVisible="{Binding MenuBarIsVisible}"
              AbsoluteLayout.LayoutBounds="0,1,1,50"
              AbsoluteLayout.LayoutFlags="PositionProportional,WidthProportional">
            <!-- App Theme Apply -->
            <Grid.BackgroundColor>
                <AppThemeBinding Light="LightGray"
                                 Dark="#333333"/>
            </Grid.BackgroundColor>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Label x:Name="FontSizeLabel"
                   Grid.Column="1"
                   Style="{StaticResource PrimaryTextStyle}"
                   VerticalOptions="Center"
                   HorizontalOptions="End"
                   Margin="0,0,10,0">
                <Label.TextColor>
                    <AppThemeBinding Light="Black"
                                     Dark="White"/>
                </Label.TextColor>
            </Label>
            <Button Grid.Column="2"
                    Text="+"
                    Clicked="OnIncreaseFontSizeClicked"
                    CornerRadius="5"
                    BorderWidth="1"
                    VerticalOptions="Center"
                    HorizontalOptions="End"
                    Margin="0,0,10,0">
                <Button.BackgroundColor>
                    <AppThemeBinding Light="LightGray"
                                     Dark="DarkGray"/>
                </Button.BackgroundColor>
                <Button.TextColor>
                    <AppThemeBinding Light="Black"
                                     Dark="White"/>
                </Button.TextColor>
                <Button.BorderColor>
                    <AppThemeBinding Light="#808080"
                                     Dark="#CCCCCC"/>
                </Button.BorderColor>
            </Button>
            <Button Grid.Column="3"
                    Text="-"
                    Clicked="OnDecreaseFontSizeClicked"
                    CornerRadius="5"
                    BorderWidth="1"
                    VerticalOptions="Center"
                    HorizontalOptions="End"
                    Margin="0,0,10,0">
                <Button.BackgroundColor>
                    <AppThemeBinding Light="LightGray"
                                     Dark="DarkGray"/>
                </Button.BackgroundColor>
                <Button.TextColor>
                    <AppThemeBinding Light="Black"
                                     Dark="White"/>
                </Button.TextColor>
                <Button.BorderColor>
                    <AppThemeBinding Light="#808080"
                                     Dark="#CCCCCC"/>
                </Button.BorderColor>
            </Button>
            <Button Grid.Column="4"
                    Text="Hide"
                    Clicked="OnHideMenuBarClicked"
                    CornerRadius="5"
                    BorderWidth="1"
                    VerticalOptions="Center"
                    HorizontalOptions="End"
                    Margin="0,0,10,0">
                <Button.BackgroundColor>
                    <AppThemeBinding Light="LightGray"
                                     Dark="DarkGray"/>
                </Button.BackgroundColor>
                <Button.TextColor>
                    <AppThemeBinding Light="Black"
                                     Dark="White"/>
                </Button.TextColor>
                <Button.BorderColor>
                    <AppThemeBinding Light="#808080"
                                     Dark="#CCCCCC"/>
                </Button.BorderColor>
            </Button>
        </Grid>
    </AbsoluteLayout>
</ContentPage>

解决方案尝试

1. 替换为PanGestureRecognizer处理滑动

SwipeGesture在Android上存在兼容性问题,改用PanGesture可以更可靠地检测滑动:

  • 取消注释代码中PanGestureRecognizer的部分,修改为:
<AbsoluteLayout.GestureRecognizers>
    <PanGestureRecognizer PanUpdated="OnPanUpdated"/>
</AbsoluteLayout.GestureRecognizers>
  • 在后台代码中实现OnPanUpdated方法,判断滑动方向和阈值:
private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
    const int swipeThreshold = 50; // 滑动触发阈值,可根据需求调整

    switch (e.StatusType)
    {
        case GestureStatus.Completed:
            if (e.TotalX > swipeThreshold)
            {
                // 触发右滑逻辑
                OnRightSwipped(sender, null);
            }
            else if (e.TotalX < -swipeThreshold)
            {
                // 触发左滑逻辑
                OnLeftSwipped(sender, null);
            }
            break;
    }
}

2. 避免CollectionView拦截横向触摸事件

Android上CollectionView的原生控件可能会消耗横向触摸事件,添加以下设置:

  • 给CollectionView设置HorizontalScrollBarVisibility="Never",禁用横向滚动:
<CollectionView x:Name="collectionView"
                Grid.Row="1"
                ItemsSource="{Binding Verses}"
                ItemsLayout="VerticalList"
                VerticalOptions="Fill"
                HorizontalOptions="Fill"
                HorizontalScrollBarVisibility="Never">

3. 调整手势识别层级

把SwipeGestureRecognizer移到承载CollectionView的Grid上,确保手势能被正确捕获:

<Grid RowDefinitions="Auto, *, Auto"
      VerticalOptions="Fill"
      HorizontalOptions="Fill"
      AbsoluteLayout.LayoutBounds="0,0,1,1"
      AbsoluteLayout.LayoutFlags="All">
    <Grid.GestureRecognizers>
        <SwipeGestureRecognizer Direction="Left" Swiped="OnLeftSwipped"/>
        <SwipeGestureRecognizer Direction="Right" Swiped="OnRightSwipped"/>
    </Grid.GestureRecognizers>
    <!-- 其他Grid内容 -->
</Grid>

内容的提问来源于stack exchange,提问作者David Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 11:43:11