关于 silverlight:Windows Phone 7 页面转换性能不佳(卡顿)

Bad performance (stuttering) with Windows Phone 7 Page Transitions

我尝试使用 Toolkit 进行页面转换,但所有动画都卡顿了。在另一个问题中,有人建议我不要使用工具包,所以我自己实现了所有动画并手动触发它们。例如导航到另一个页面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBox listBox = sender as ListBox;
    if (null == listBox) return;
    Data.Category item = listBox.SelectedItem as Data.Category;
    if (null == item) return;

    Uri uri = new Uri(App.MakeResourcePathTo(item.Page), UriKind.Relative);

    Storyboard storyboard = Application.Current.Resources["FlipForwardOut"] as Storyboard;
    Storyboard.SetTarget(storyboard, LayoutRoot);
    EventHandler completedHandler = delegate { };
    completedHandler = delegate
            {
                NavigationService.Navigate(uri);

                storyboard.Stop();
                storyboard.Completed -= completedHandler;
            };
    storyboard.Completed += completedHandler;
    storyboard.Begin();

    listBox.SelectedIndex = -1;
}

代码正常吗?
据我了解,不应该有其他任何东西与该代码并行运行。这正是我想要的,因为这样就不会干扰我的动画并使其变慢。

这是另一个代码片段。这显示了我如何处理后退动画。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
    e.Cancel = true;
    Storyboard storyboard = Application.Current.Resources["FlipBackwardOut"] as Storyboard;
    Storyboard.SetTarget(storyboard, LayoutRoot);
    EventHandler completedHandler = delegate { };
    completedHandler = delegate
    {
        storyboard.Stop();
        storyboard.Completed -= completedHandler;

        NavigationService.GoBack();
    };
    storyboard.Completed += completedHandler;
    storyboard.Begin();
}

该代码有什么问题,可能导致性能问题吗?

动画很简单,只有线性动画:

1
2
3
4
5
6
7
8
9
10
<Storyboard x:Key="FlipForwardOut">
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
        <LinearDoubleKeyFrame KeyTime="0" Value="0"/>
        <LinearDoubleKeyFrame KeyTime="0:0:0.4" Value="70"/>
    </DoubleAnimationUsingKeyFrames>
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)">
        <LinearDoubleKeyFrame KeyTime="0" Value="1"/>
        <LinearDoubleKeyFrame KeyTime="0:0:0.4" Value="0.1"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

我已经认识到一件事:当我导航到全景页面时,全景页面的动画与我的页面转换动画并行运行。全景页面的内置动画让标题滑入,全景项目也滑入到位。因此,有一些平移动画与我的页面转换(基本上是旋转和不透明度)平行运行。
我能否以某种方式阻止全景图播放它自己的动画,或者将它们延迟到我的页面过渡动画完成为止?

我的页面过渡还有一个问题:当我导航到另一个页面并播放动画时,当动画完成时(LayoutRoot 已旋转到 Y=70,并且它的 opacity=0)然后原来的布局显示几毫秒(LayoutRoot 旋转 Y=0 和 opacity=1),然后导航到下一页并开始下一页上的动画。
这是为什么呢?

我希望,有人可以帮助我。
在花了这么多小时后,我感到非常沮丧。无论我尝试了什么,动画都表现不佳,它们在模拟器和设备上都卡顿了。
手机预装应用的动画动画流畅。我不明白这一点。 :(

  • 我还在考虑使用 WriteableBitmap 来制作我的控件的屏幕截图并为其设置动画。将是我不想做的额外工作,只是为了获得流畅的动画。但是,它不能修复卡顿的全景图的烘焙动画。


您的动画代码看起来没问题,尽管您可能没有处理许多场景,所以您可能想看看 Kevin Marshall 的 Page Transitions Sample(我已经发现比 Toolkit 转换执行得更好)。
但是,假设您的动画代码很好,并且您在使用工具包转换时遇到了类似的卡顿,您是否在页面的构造函数中做任何事情?在构造函数中加载和/或处理视图模型或数据是很常见的,这将导致动画延迟,因为这是在 UI 线程上完成的。您应该尽可能多地进行初始化,直到您的页面被 OnNavigatedTo 覆盖。

  • 我已经将所有数据加载代码移到了 OnNavigatedTo 处理程序中的页面转换动画的 Completed-handler 中,因此这不会干扰我的动画。我会检查你发布的链接。谢谢你。
  • 好的,那么性能问题是否在所有页面上都很明显,或者只是特定的页面(即您提到的全景页面)?
  • 我又做了一些测试。导航到普通页面时,似乎我自己的页面转换不会卡顿。我已禁用全景页面上的页面输入动画。在我看来,全景烘焙动画结结巴巴。而且,它看起来不像手机通讯录应用程序的动画那么好,例如。看起来更糟,性能更差,酷!调试版本和发布版本的行为是相同的。还有什么想法吗?
  • 好的,所以如果我们将其缩小到全景页面,那么下一个问题是:全景中有什么内容以及它是如何/何时初始化的?与 Pivot 控件不同,所有 PanoramaItems 都在启动时加载。如果有任何数据绑定正在进行,那么它们可能会导致动画卡顿,因为绑定发生在 UI 线程上,您应该等到 LayoutUpdated 事件后再设置它们。您可以使用我在此答案中描述的相同方法:stackoverflow.com/questions/4709019/...
  • OnNavigatedTo 方法中没有太多代码,在页面的 Loaded 处理程序中根本没有代码。但是,我现在已经将代码移到了构造函数中,现在有:vm.DoneLoading += (s, e) => { Dispatcher.BeginInvoke(delgate { list.ItemsSource = vm.Items; }); };panoramaControl.InvokeOnLayoutChanged(delegate { vm.LoadData(); });。 vm.LoadData() 之前在 OnNavigatedTo 方法中。但是,仅加载静态数据,因此根本不会影响性能。还有什么我可以做的,还是现在是性能最佳的解决方案?
  • 当然应该是 InvokeOnLayoutUpdated 而不是 InvokeOnLayoutChanged
  • 现在性能是否可以接受,还是仍然明显缓慢?
  • 虽然只有几行代码,但现在性能似乎更好了。直接在 OnNavigatedTo 方法中与在 LayoutUpdated 方法中执行(小,不耗时)代码真的有这么大的区别吗?但是,我还无法在设备上进行测试。在模拟器中看起来不错。有时它会轻微结结巴巴。它仍然不像预装应用程序的动画那样流畅。
  • 不幸的是,在 3rd 方应用程序中无法在 100% 的时间内获得 100% 流畅的动画。绝对值得在设备上进行测试,特别是如果你有一台非常强大的 PC,虽然我发现页面动画性能相当。
  • 嗯,为什么预装的应用程序是 100% 流畅的?它们不是 Silverlight 应用程序吗?他们是本地人吗?无论如何,非常感谢您的帮助!!
  • 预装的应用程序(由 Microsoft 及其合作伙伴创建)可以访问比我们低级的第 3 方应用程序开发人员更低级别的 API :)
  • 最后一个问题:我可以确定 LayoutUpdated 总是在 OnNavigatedTo 之后触发吗?