【问题标题】:Bad performance (stuttering) with Windows Phone 7 Page TransitionsWindows Phone 7 页面转换性能不佳(卡顿)
【发布时间】:2011-01-22 00:59:47
【问题描述】:

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

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

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

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

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();
}

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

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

<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 来制作我的控件的屏幕截图并为其设置动画。将是我不想做的额外工作,只是为了获得流畅的动画。但是,它不能修复卡顿的全景图的烘焙动画。

标签: silverlight performance animation windows-phone-7


【解决方案1】:

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

【讨论】:

  • 我已经将所有数据加载代码移到了 OnNavigatedTo 处理程序中的页面转换动画的 Completed-handler 中,这样就不会干扰我的动画。我会检查你发布的链接。谢谢你。
  • 好的,性能问题是否在所有页面上都很明显,或者只是特定页面(即您提到的全景页面)?
  • 我做了更多的测试。导航到普通页面时,似乎我自己的页面转换不会卡顿。我已禁用全景页面上的页面输入动画。在我看来,全景烘焙动画结结巴巴。而且,它看起来不像手机通讯录应用程序的动画那么好,例如。看起来更糟,性能更差,酷!调试版本和发布版本的行为是相同的。还有什么想法吗?
  • 好的,所以如果我们将范围缩小到全景页面,那么下一个问题是:全景中有什么内容以及它是如何/何时初始化的?与 Pivot 控件不同,所有 PanoramaItems 都在启动时加载。如果有任何数据绑定正在进行,那么它们可能会导致动画卡顿,因为绑定发生在 UI 线程上,您应该等到 LayoutUpdated 事件后再设置它们。您可以使用我在此答案中描述的相同方法:stackoverflow.com/questions/4709019/…
  • OnNavigatedTo 方法中没有太多代码,页面的 Loaded 处理程序中根本没有代码。但是,我现在已经将代码移到了构造函数中,现在有:vm.DoneLoading += (s, e) =&gt; { Dispatcher.BeginInvoke(delgate { list.ItemsSource = vm.Items; }); }; 和 panoramaControl.InvokeOnLayoutChanged(delegate { vm.LoadData(); });。 vm.LoadData() 之前在 OnNavigatedTo 方法中。但是,仅加载静态数据,因此根本不会对性能产生影响。还有什么我可以做的吗?或者它现在是性能最佳的解决方案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多