【问题标题】:Xamarin Forms Grid Boxview swipe gesture multi selectXamarin Forms Grid Boxview 滑动手势多选
【发布时间】:2018-12-07 04:29:30
【问题描述】:

我有一个简单的 Xamarin.Forms 页面,其中包含 BoxViews 的网格布局。我希望能够通过滑动手势同时选择这些框视图。我怎样才能做到这一点?

我想建立一种瓦片地图,以便更容易选择框视图。我想轻松实现这一目标。只有滑动不是很好,因为只会选择“一个”框视图。

这是我目前所拥有的:

XAML

    <ContentPage.Content>
        <Grid x:Name="pageGrid" RowSpacing="1" ColumnSpacing="1" VerticalOptions="Center" HorizontalOptions="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
        </Grid>
    </ContentPage.Content>

后面的代码:

public Page()
    {
        InitializeComponent();

        int columnIndex = 0;
        for (int rowIndex = 0; rowIndex <= 8; rowIndex++)
        {
            BoxView boxview = new BoxView { BackgroundColor = Color.White };
            SwipeGestureRecognizer swipeGestureRecognizer = new SwipeGestureRecognizer();
            swipeGestureRecognizer.Swiped += (sender, args) =>
            {
                if (boxview.BackgroundColor == Color.White)
                {
                    boxview.BackgroundColor = Color.Gray;
                }
                else if (boxview.BackgroundColor == Color.Gray)
                {
                    boxview.BackgroundColor = Color.White;
                }
            };

            swipeGestureRecognizer.Threshold = 1;
            swipeGestureRecognizer.Direction = SwipeDirection.Left | SwipeDirection.Right;
            
            TapGestureRecognizer tapGestureRecognizer = new TapGestureRecognizer();
            tapGestureRecognizer.Tapped += (sender, args) =>
            {
                if (boxview.BackgroundColor == Color.White)
                {
                    boxview.BackgroundColor = Color.Gray;
                }
                else if (boxview.BackgroundColor == Color.Gray)
                {
                    boxview.BackgroundColor = Color.White;
                }
            };
            
            boxview.GestureRecognizers.Add(swipeGestureRecognizer);
            boxview.GestureRecognizers.Add(tapGestureRecognizer);

            if (rowIndex == 4 && columnIndex == 3)
            {
                boxview.BackgroundColor = Color.Red;
            }

            pageGrid.Children.Add(boxview, columnIndex, rowIndex);

            if (rowIndex != 8) continue;
            if (columnIndex == 6) return;
            columnIndex += 1;
            rowIndex = -1;
        }
    }

现在每次滑动操作,只会选择一个 boxview!

【问题讨论】:

    标签: xamarin.forms grid multi-select swipe-gesture


    【解决方案1】:

    我对此进行了一些尝试,并提出了一些想法,并将在最后部分实现。

    我认为滑动手势不会使这项工作以我认为您希望它工作的方式工作。看起来滑动手势恰好触发了一次,在手指从屏幕上抬起的那一刻,这对我来说不是理想的体验,因为这意味着即使你能弄清楚总共滑动了哪些框(我'不确定这是否可以做到)他们都会等到你抬起手指来改变颜色。

    我刚刚提出的想法是使用平移手势,因为每当检测到运动时,该手势会非常频繁地触发。 pan 和 swipe 似乎都有这样的约束,即一旦事件与单个 boxview 相关联,即使您的手指越过其他 box,该事件也不会在任何其他 boxview 中触发回调。但是,我认为如果您使用平移手势,这可以克服。平移手势每次触发时都会为您提供总平移偏差,并且鉴于手势回调本身将在平移开始的 boxview 内持续触发(而不是在任何其他框中),这意味着您同时拥有初始位置和每次平移运动的总偏差。从理论上讲,您拥有完成这项工作所需的所有信息,但您需要对事件进行一些智能处理。这可能会让人头疼,但是如果您可以构建自己的网格,使其足够聪明地了解每个 boxview 与其他 boxview 的关系,您就可以在平移手势事件进入时映射它们,并根据需要使特定的 boxview 更改颜色。

    编辑:应提问者的要求,我构建了一些示例代码来执行此操作。有必要重新添加单独的点击事件并使其正确“切换”,而不是仅仅根据您想要的逻辑进行选择。可能还需要进行其他调整,但这证明了这一概念。

        public Page()
        {
            InitializeComponent();
    
            var columnIndex = 0;
            for (var rowIndex = 0; rowIndex <= 8; rowIndex++)
            {
                var boxview = new BoxView { BackgroundColor = Color.White };
                var swipeGestureRecognizer = new PanGestureRecognizer();
    
                swipeGestureRecognizer.PanUpdated += (sender, args) =>
                {
                    var boxView = (BoxView) sender;
                    var panBaseBounds = boxView.Bounds;
                    var eventX = panBaseBounds.X + args.TotalX;
                    var eventY = panBaseBounds.Y + args.TotalY;
                    foreach (var gridChild in pageGrid.Children)
                    {
                        var testBounds = gridChild.Bounds;
                        if (testBounds.X <= eventX && eventX <= testBounds.X + testBounds.Width &&
                            testBounds.Y <= eventY && eventY <= testBounds.Y + testBounds.Height)
                        {
                            gridChild.BackgroundColor = Color.Gray;
                            break;
                        }
                    }
                };
    
                boxview.GestureRecognizers.Add(swipeGestureRecognizer);
    
                if (rowIndex == 4 && columnIndex == 3)
                {
                    boxview.BackgroundColor = Color.Red;
                }
    
                pageGrid.Children.Add(boxview, columnIndex, rowIndex);
    
                if (rowIndex != 8) continue;
                if (columnIndex == 6) return;
                columnIndex += 1;
                rowIndex = -1;
            }
        }
    

    【讨论】:

    • 我会花几个小时看看我能为你准备什么。
    • @E75 我在答案末尾添加了一个代码示例。
    猜你喜欢
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    相关资源
    最近更新 更多