【发布时间】:2022-11-10 19:33:17
【问题描述】:
我尝试为 GraphicsView 的内容设置动画,
private void OnLoaded(object sender, EventArgs e)
{
var animation = new Animation(v => AngleSpan = v, 0, 360D, Easing.CubicInOut);
animation.Commit(this, "AngleAnimation", 8, 1500);
}
但是动画很生涩(当两个图像之间有 8ms 的延迟时,20ips 应该让我更接近 120ips)。
通过在调用 GraphicsView 的 Invalidate 之前和在我的 IDrawable 的 Draw 方法中添加一个 Debug.WriteLine,我意识到 Draw 方法平均只有 3 次调用一次。
Invalidate
Invalidate
Draw
Invalidate
Invalidate
Draw
Invalidate
Invalidate
Invalidate
Draw
Invalidate
Invalidate
Invalidate
Draw
[...]
对 Invalidate 的调用不应该确保始终调用 Draw 方法吗?
如果不是这样,我必须有什么选择才能获得流畅的动画?
编辑
我正在添加一些与 cmets 中提出的问题相关的上下文和说明:
动画通过 AngleSpan 属性的设置器触发对“Invalidate”的调用。
public class PieChart : GraphicsView
{
private double _angleSpan = 360D;
public double AngleSpan
{
get => _angleSpan;
private set
{
_angleSpan = value;
Debug.WriteLine("Invalidate");
Invalidate();
}
}
public PieChart()
{
Drawable = new PieChartDrawable(this);
Loaded += OnLoaded;
}
private void OnLoaded(object sender, EventArgs e)
{
Loaded -= OnLoaded;
var animation = new Animation(v => AngleSpan = v, 0, 360D, Easing.CubicInOut);
animation.Commit(this, "AngleAnimation", 8, 1500);
}
}
出于测试的目的,我把Draw的内容去掉了,以为问题出在过于复杂的绘图上,但不管有没有内容,问题依旧。
public class PieChartDrawable : IDrawable
{
private readonly PieChart _chart;
public PieChartDrawable(PieChart chart)
{
_chart = chart;
}
public void Draw(ICanvas canvas, RectF dirtyRect)
{
Debug.WriteLine("Draw");
}
}
我在附加和不附加调试器的情况下进行了测试(在调试和发布中),在所有情况下都是一样的。
我还没有在移动设备或模拟器上进行测试(仅在 Windows 项目上,因为这是我首先感兴趣的)。
【问题讨论】:
-
您需要提供更多详细信息。如果你开始了一个动画,它不应该自己运行吗?我见过的例子没有明确的
Invalidate。你在哪里打电话Invalidate?这是在 Windows 上进行的测试还是什么? [如果是移动模拟器,请在实际设备上测试。]您是否尝试过不使用调试器运行,看看它是否运行更顺畅?你是否做过最简单的测试:一个小的纯色对象,视图中没有其他内容?在我看来,有些东西正在导致Draw“花费太长时间”,因此在图形系统准备好再次绘制之前发生了多次无效。 -
您可以查看此doc。它讲述了无效。您能否提供更多代码,以便我可以重现您描述的情况。
-
@JianweiSun 我知道文档的这一部分,正是这部分让我说从 GraphicsView 调用无效必然意味着从其 Drawable 调用 Draw。至于提供一段代码来重现问题,一切都在我的编辑中;只需将 PieChart 放在默认 maui 项目的 MainPage 上,运行它并在控制台中查看 Draw 方法没有被系统地调用(与文档所暗示的相反)。
-
@杰里米A。收到。顺便问一下,您是否尝试过生成
.apk文件并在实际设备上进行测试,看看它是否具有流畅的动画效果? -
@JianweiSun奇怪的是,在物理android设备上,每次调用Invalidate方法都会触发重绘(并且动画很流畅)。我在不同的 PC 上进行了测试,看看我的问题是否来自我的配置(Rysen 7 5800 + RX6600 + 32GB ram),但问题出现在任何 Windows 机器(intel 或 amd,专用或集成 gpu)上。
标签: maui