C# 如何阻止应用程序在RotateTo上崩溃?
我正在用Xamarin.Forms编写一个flashcard应用程序,其中我使用了一个包含flashcard文本标签的表单。点击表单时,表单将翻转180度,标签上的文本将发生变化。 我这样做的方式是通过旋转“RotateTo”的形状到90度。之后,我更改标签上的文本,并将旋转更改为-90度。之后,我再次使用“RotateYTo”旋转最后90度(从-90旋转回0),以实现无缝旋转。 下面是它的外观: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
//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创建一个线程以获得更多讨论。