Xamarin Forms Grid Boxview жест смахивания мульти выбор - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть простая страница 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;
        }
    }

Теперь для каждого действия смахивания будет выбран только один вид окна!

Layout

1 Ответ

0 голосов
/ 05 декабря 2018

Я немного поиграл с этим и придумал несколько идей, которые последуют, с частичной реализацией в конце.

Я не думаю, что жест смахивания сделает эту работукак я думаю ты хочешь чтобы это работало.Похоже, что жест смахивания срабатывает ровно один раз, когда палец поднимается с экрана, что для меня не является идеальным опытом, потому что это означает, что даже если бы вы могли выяснить, какие ящики в общей сложности были пролистаны (яя не уверен, что это можно сделать) они все подождут, пока вы не уберете палец, чтобы изменить цвет.

Идея, которую я только что придумал, - это использовать жест панорамирования, потому что он срабатывает очень часто при движении.обнаружен.Кажется, что и панорамирование, и пролистывание имеют ограничение, заключающееся в том, что, как только событие будет связано с одним окном просмотра, событие не будет вызывать обратные вызовы в любых других, даже если ваш палец проходит над другими полями.Тем не менее, я думаю, что это можно преодолеть, если использовать жест панорамирования.Жест панорамирования дает вам полное отклонение панорамирования каждый раз, когда он срабатывает, и, учитывая, что сам обратный вызов жеста будет постоянно запускаться внутри окна просмотра, где началось панорамирование (а не в каких-либо других боксах), это означает, что у вас есть и начальное местоположение, иобщее отклонение с каждым движением панорамирования.Теоретически у вас есть вся информация, необходимая для выполнения этой работы, но вам нужно иметь умную обработку события.Это может быть головной болью, но если вы можете построить свою сетку так, чтобы она была достаточно умной, чтобы знать, как каждый 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;
        }
    }
...