Как остановить сбой приложения на RotateYTo? - PullRequest
1 голос
/ 20 сентября 2019

Я пишу приложение для карточки в Xamarin. Формы, где я использую форму, содержащую ярлык с текстом карточки.При нажатии на форму она перевернется на 180 градусов, и текст на этикетке изменится.Я делаю это, поворачивая форму с «RotateYTo» на 90 градусов.После этого я меняю текст на этикетке и поворачиваю на -90 градусов.После этого я снова использую «RotateYTo», чтобы повернуть последние 90 градусов (поворачивается от -90 до 0), чтобы сделать плавное вращение.Вот как это выглядит:

//Rotating the frame to half of the full rotation
            await frame.RotateYTo(90, 200, Easing.SinIn);

            //Changing the text on the label
            switch (label.Text)
            {
                case "A":
                    label.Text = "B";
                    break;
                case "B":
                    label.Text = "A";
                    break;
                default:
                    break;
            }

            //Changing the rotation to -90 degrees to make sure that the "180 degrees rotation" is seamingless and that the text isn't flipped
            frame.RotationY = -90;

            //Rotating the rest of the rotation
            await frame.RotateYTo(0, 200, Easing.SinOut);

И соответствующий XAML:

<!-- The frame that i will be rotating-->
        <Frame x:Name="frame" Grid.Row="1" Margin="40, 0, 40, 0" BackgroundColor="LightGray" HeightRequest="120">

            <Frame.GestureRecognizers>
                <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
            </Frame.GestureRecognizers>

            <!-- A label that acts as the flashcard's text inside of the frame-->
            <Label x:Name="label" Text="A" FontSize="120" HorizontalOptions="Center" VerticalOptions="Center"/>

        </Frame>

Проблема заключается в том, что сбой происходит каждый раз, когда начинает выполняться вторая функция RotateYTo.Приложение немедленно зависает и отладка прекращается.Не исключение не выбрасывается, и это «падение», кажется, появляется только на Android 9.

Я проверил это на телефоне Android 5.1, и он работает нормально, но на Android 9 он вылетает как в эмуляторе, так и в тесте.phone.

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


[...]

//Waiting for the previous animation to finish
            while (frame.RotationY != 90)
            {

            }

            //Changing the rotation to -90 degrees to make sure that the "180 degrees rotation" is seamingless and that the text isn't flipped
            frame.RotationY = -90;

            //Rotating the rest of the rotation
            await frame.RotateYTo(0, 200, Easing.SinOut);

Я также попытался добавить метод «ConfigureAwait» в мою первую функцию, используя «true» и «false» в качестве аргументов:

//Rotating the frame to half of the full rotation
            await frame.RotateYTo(90, 200, Easing.SinIn).ConfigureAwait(false);

Кроме того, я попытался сохранитьанимация как отдельная задача, а затем «ожидая» ее перед следующей анимацией:

//Rotating the frame to half of the full rotation
            Task<bool> animFrameY = frame.RotateYTo(90, 200, Easing.SinIn);
            await animFrameY;

[...]

//Waiting for the first animation to finish
            animFrameY.Wait();

Я также пытался завершить (принудительно остановить) первую анимацию, независимо от того, закончена она или нет, перед выполнением второйанимации с использованием метода «CancelAnimations» на моем кадре:

//Terminating all animations on the frame
            ViewExtensions.CancelAnimations(frame);

Все это, однако, не сработало, и приложение по-прежнему зависает иисключение не выдается.

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

РЕДАКТИРОВАТЬ: У меня есть сейчасзагрузил этот проект как репозиторий GitHub:

https://github.com/KMilkevych/Flashcard-application

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Я тестирую ваш код. Если я использую TapGestureRecognizer, как и ваш пример, иногда у меня нет никаких эффектов, поэтому я пытаюсь использовать PanGestureRecognizer, чтобы сделать это, у меня нет проблем и достичь ваших целей.

 <Frame
        x:Name="frame"
        Grid.Row="1"
        Margin="40,0,40,0"
        BackgroundColor="LightGray"
        HeightRequest="120">

        <Frame.GestureRecognizers>
            <!--<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />-->
            <PanGestureRecognizer PanUpdated="PanGestureRecognizer_PanUpdated" />
        </Frame.GestureRecognizers>

        <!--  A label that acts as the flashcard's text inside of the frame  -->
        <Label
            x:Name="label"
            FontSize="120"
            HorizontalOptions="Center"
            Text="A"
            VerticalOptions="Center" />

    </Frame>

Пожалуйста, введите ваш код поворота в событие PanGestureRecognizer.PanUpdated.

Обновление:

enter image description here

0 голосов
/ 20 сентября 2019

Необходимо убедиться, что обновление элементов управления пользовательским интерфейсом выполняется потоком пользовательского интерфейса.Xamarin.Forms предоставляет удобный класс , который гарантирует, что действия выполняются этим потоком пользовательского интерфейса.Вот пример того, как вы можете «обернуть» свой код вращения

Device.BeginInvokeOnMainThread (async () => 
{
   await frame.RotateYTo(0, 200, Easing.SinOut);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...