【问题标题】:How do i stop app from crashing on RotateYTo?如何停止应用从rotateyto崩溃?
【发布时间】:2020-01-21 17:20:25
【问题描述】:

我正在 Xamarin.Forms 中编写一个抽认卡应用程序,其中我使用一个包含抽认卡文本标签的表单。当表单被点击时,它会翻转 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 上,它在模拟器和测试手机中都崩溃了。

我认为这可能是由于同时执行了两个旋转函数(由于 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

【问题讨论】:

  • 我已经在 Android 5.1 手机上测试过,它运行良好,但在 Android 9 上,它在模拟器和测试手机中都崩溃了。,你的意思是它可以运行在 Android 5.1 上,但在 android 9 上崩溃了?你能在github上提供一个样本吗,我会加载你的样本进行测试。
  • @CherryBu-MSFT 我现在已经将此项目上传到我的 GitHub 页面:github.com/KMilkevych/Flashcard-application

标签: c# asynchronous animation xamarin.forms


【解决方案1】:

您需要确保更新 UI 控件是由 UI 线程执行的。 Xamarin.Forms 提供了一个方便的class,可确保此 UI 线程正在执行操作。这是一个如何“包装”轮换代码的示例

Device.BeginInvokeOnMainThread (async () => 
{
   await frame.RotateYTo(0, 200, Easing.SinOut);
});

【讨论】:

  • 您好,我已经尝试了您的解决方案,方法是在您展示的 UI 线程上调用两个动画。它可以防止崩溃,但根本不显示第一个动画(它只是被跳过),只显示第二个动画。
【解决方案2】:

我测试你的代码,如果我像你的示例一样使用 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 事件中。

更新:

【讨论】:

  • 嗨,我已经尝试过您的解决方案,但是将代码放在“PanGestureRecognizer PanUpdated 事件”中似乎并没有改变任何东西,除了触发事件所需的操作。在动画执行期间我仍然遇到冻结/崩溃。
  • 抱歉回复晚了,我再次测试你的样品,现在它工作正常,我没有任何问题。我把我的截图放在回复上。您也可以使用 PanGestureRecognizer 来执行此操作,但您需要使用手指滑动。
  • 这可能只是我的设备的问题;我已经上传了我的电脑上发生的崩溃视频(由于视频太大,我无法将其添加到问题中):mediafire.com/file/2j1t2devzmtw4kg/animationAppCrash.mp4/file
  • @Kostyantyn,你说它只是在Android 9上崩溃,其他设备工作正常,所以我认为你的代码没有问题,你可以尝试在github上创建一个线程以获得更多讨论。
猜你喜欢
  • 1970-01-01
  • 2012-06-04
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
相关资源
最近更新 更多