【问题标题】:Laggy animation on Windows PhoneWindows Phone 上的滞后动画
【发布时间】:2015-03-30 18:37:20
【问题描述】:

您好,我遇到了无法解决的性能问题。使用 Blend,我创建了一个显示和隐藏网格的动画。它在切换开关按钮被选中时被调用,并且它工作。问题是,它的工作非常滞后,并在延迟几秒钟后调用。我在诺基亚 Lumia 920 上测试该应用程序。您能帮我找出问题所在吗?

这是使用 blend 创建的动画代码:

<VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="Collapsing">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:0.5" />
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Hidden">
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="CollapsingGrid">
                            <EasingDoubleKeyFrame KeyTime="0"
                                                  Value="95" />
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <CubicEase EasingMode="EaseOut" />
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="anonymousOnLabel">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0" />
                            <EasingDoubleKeyFrame KeyTime="0:0:1"
                                                  Value="91" />
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="SettingsSharePicTglBtn">
                            <EasingDoubleKeyFrame KeyTime="0"
                                                  Value="95" />
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0" />
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Unhidden">
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="CollapsingGrid">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0" />
                            <EasingDoubleKeyFrame KeyTime="0:0:1"
                                                  Value="95">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <CubicEase EasingMode="EaseOut" />
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="anonymousOnLabel">
                            <EasingDoubleKeyFrame KeyTime="0"
                                                  Value="91" />
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0" />
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="SettingsSharePicTglBtn">
                            <EasingDoubleKeyFrame KeyTime="0"
                                                  Value="0" />
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="95" />
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

我通过以下方式调用它:

private void TglBtn_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            if ((bool)((ToggleSwitchButton)sender).IsChecked)
            {
                VisualStateManager.GoToState(this, "Unhidden", true);
            }
            else
            {
                VisualStateManager.GoToState(this, "Hidden", true);
            }
        }

【问题讨论】:

  • “工作真的很慢”?你的意思是即使最终运行它也不会流畅地动画?
  • 尝试将 xaml 中的 CacheMode="BitmapCache" 添加到您正在制作动画的元素中。
  • @JoachimIsaksson - 没错。效果如下:我点了拨动开关,要等0.8秒左右,塌陷的动画开始了,但是不流畅,好像掉帧一样。
  • @krdx - 我想它可能会有所帮助,但它仍然不是 Android/iOS 流畅。我的猜测是我在动画中搞砸了,你能帮我验证一下吗?
  • @krdx BitmapCache 在为宽度和高度设置动画时是否会产生任何效果,从而强制重建视觉树? (诚​​实的问题,我只是一直认为它没有:))

标签: c# animation windows-phone-8 windows-phone


【解决方案1】:

我建议不要为 WidthHeight 属性设置动画。每次这些属性发生变化时,都会在可视化树上执行一次完整的测量/排列过程,这非常昂贵。相反,您应该尝试在网格的 RenderTransform 上从 1.0 到 0.0 设置 Scale 动画。

现在,您可能正在为高度设置动画,因为您希望堆叠在网格下的东西向上移动以填充网格占用的空间。在这种情况下,您可能需要执行一些视觉技巧,例如对网格下方的事物进行动画平移以将它们向上移动,然后在动画的最后,作为最后一个关键帧,您可以重置 RenderTransforms 并折叠网格。然后,您将只经历一次测量/排列,而不是每个动画帧一次。

最后,我建议阅读有关 Windows Phone 性能注意事项的内容。这是一个很好的文档:http://bit.ly/15cExFz

这两个演示文稿非常棒。我不能推荐他们。 http://channel9.msdn.com/events/PDC/PDC10/CD03 & http://channel9.msdn.com/Events/Build/2012/3-048

【讨论】:

  • 您的第二段是准确的。我在网格下堆叠了一些元素,这就是使用 Height 属性的原因。我将检查您的解决方案并提供材料,并会回答是否解决了问题。谢谢你。 :)
【解决方案2】:

我遇到过类似的问题,但我使用 DoubleAnimation 为 PlaneProjection 的 RotationX、RotationY 属性设置了动画。从这个article 中找到了问题的解决方案。它添加了以 0.1 结尾的“神奇”数字——这告诉系统这是基于控件宽度的比率,它是属性的 hack 过载,但在某些情况下它会带来真正的性能增长。

<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="anonymousOnLabel">
    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.1" />
    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="91.1" />
</DoubleAnimationUsingKeyFrames>

当然,直接为 Width 和 Height 属性设置动画也不是什么好主意,因为这将是 Dependent Animation 并且会对性能产生影响。

【讨论】:

    猜你喜欢
    • 2021-09-23
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 2016-09-22
    • 2015-04-13
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多