C# 如何阻止应用程序在RotateTo上崩溃?

C# 如何阻止应用程序在RotateTo上崩溃?,c#,asynchronous,animation,xamarin.forms,C#,Asynchronous,Animation,Xamarin.forms,我正在用Xamarin.Forms编写一个flashcard应用程序,其中我使用了一个包含flashcard文本标签的表单。点击表单时,表单将翻转180度,标签上的文本将发生变化。 我这样做的方式是通过旋转“RotateTo”的形状到90度。之后,我更改标签上的文本,并将旋转更改为-90度。之后,我再次使用“RotateYTo”旋转最后90度(从-90旋转回0),以实现无缝旋转。 下面是它的外观: //Rotating the frame to half of the full rotation

我正在用Xamarin.Forms编写一个flashcard应用程序,其中我使用了一个包含flashcard文本标签的表单。点击表单时,表单将翻转180度,标签上的文本将发生变化。 我这样做的方式是通过旋转“RotateTo”的形状到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>
我还尝试向我的第一个函数添加一个“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();
然而,所有这些都不起作用,应用程序仍然冻结,没有抛出异常

我希望将框架旋转180度,标签上的文本应在不翻转的情况下进行更改。 我已经尝试删除了第一个动画中的“wait”关键字,这可以防止崩溃,但是这个部分只是被跳过而没有显示出来,这两个部分看起来都很难看,不是我需要的

编辑: 我现在已将此项目上载为GitHub存储库:


您需要确保更新UI控件是由UI线程执行的。Forms提供了一个方便的工具,可以确保此UI线程正在执行操作。下面是一个如何“包装”旋转代码的示例

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

您需要确保更新UI控件是由UI线程执行的。Forms提供了一个方便的工具,可以确保此UI线程正在执行操作。下面是一个如何“包装”旋转代码的示例

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

我测试你的代码,如果我像你的示例一样使用TapGestureRecognitizer,有时我没有任何效果,所以我尝试使用PangestureRecognitizer来做这件事,我没有任何问题,并且实现了你的目标

 <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>

请将旋转代码放入PangestureRecognitizer.panUpdate事件中

更新:


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

请将旋转代码放入PangestureRecognitizer.panUpdate事件中

更新:


您好,我已经尝试了您的解决方案,如您所示,在UI线程上调用了两个动画。它可以防止崩溃,但第一个动画根本不显示(只是被跳过),而只显示第二个动画。您好,我已经尝试了您的解决方案,如您所示,在UI线程上调用两个动画。它可以防止崩溃,但第一个动画根本不显示(只是被跳过),只显示第二个动画。我在安卓5.1手机上测试过,效果很好,但在安卓9上,它在模拟器和测试手机上都会崩溃。你是说它在安卓5.1上工作,但在安卓9上会崩溃?你能在github上提供一个示例吗,我会加载你的示例进行测试。@CherryBu MSFT我现在已经将这个项目上传到我的github页面:我已经在Android 5.1手机上测试了这个项目,效果很好,但在Android 9上它在模拟器和测试手机上都崩溃了。你是说它在Android 5.1上工作,但在Android 9上崩溃了?您能否在github上提供一个示例,我将加载您的示例以进行测试。@CherryBu MSFT我现在已将此项目上载到我的github页面:您好,我已尝试了您的解决方案,但将代码放入“PangestureRecognitizer PanUpdated event”(PangestureRecognitizer PanUpdate事件)中似乎不会改变任何内容,除了触发事件所需的操作。我在动画执行过程中仍然遇到冻结/崩溃。很抱歉延迟回复,我再次测试了您的示例,现在它工作正常,我没有收到任何问题。我把截图放在回复上。您也可以使用PangestureRecognitizer来执行此操作,但您需要使用手指滑动;我已经在我的电脑上上传了一段崩溃的视频(由于视频太大,我无法将其添加到问题中):@Kostyantyn,你说它只是在Android 9上崩溃,其他设备工作正常,所以我认为你的代码没有问题,你可以尝试在github创建一个线程以获得更多讨论。嗨,我已经尝试了你的解决方案,但是,将代码放入“PangestureRecognitizer PanUpdate事件”中似乎不会改变任何东西,除了触发事件所需的操作。我在动画执行过程中仍然遇到冻结/崩溃。很抱歉延迟回复,我再次测试了您的示例,现在它工作正常,我没有收到任何问题。我把截图放在回复上。您也可以使用PangestureRecognitizer来执行此操作,但您需要使用手指滑动;我在我的电脑上上传了一段崩溃的视频(由于视频太大,我无法将其添加到问题中):@Kostyantyn,你说它只是在Android 9上崩溃,其他设备工作正常,所以我认为你的代码没有问题,你可以尝试在github创建一个线程以获得更多讨论。