Xamarin Android:在覆盖on Draw方法中调用Invalidate()

发布于 2025-01-27 23:00:30 字数 778 浏览 2 评论 0原文

我正在创建一个自定义渲染器,需要显示我在Vulkan引擎中渲染的内容。为此,我有一个vulkansurfaceview,它从iOS上的metalkit.mtkview继承,以及android.views.surfaceview和isurfaceview和isurfaceholdercallback上的android上。

对于iOS,我可以简单地执行此操作,只要视图的焦点是:

public class VulkanSurfaceView : MTKView, IVulkanAppHost
{
    ...

    public override void Draw()
    {
        Renderer.Tick();
        base.Draw();
    }
}

但是,在Android上,我必须这样做,在Android上,我从OnDraw方法中调用Invalidate(),否则是只打电话一次。我认为此代码闻起来有点闻,我不确定这是这样做的“好”方式。我的解决方案还可以吗?如果没有,有人有更好的主意吗?

public class VulkanSurfaceView : SurfaceView, ISurfaceHolderCallback, IVulkanAppHost
{
    ...

    protected override void OnDraw(Canvas? canvas)
    {
        Renderer.Tick();
        base.OnDraw(canvas);
        Invalidate();
    }
}

I am creating a custom renderer, that needs to display whatever I have rendered in my Vulkan engine. For this I have a VulkanSurfaceView, which inherits from MetalKit.MTKView on iOS, and from Android.Views.SurfaceView and ISurfaceHolderCallback on Android.

For iOS I can simply do this, which will draw a new frame continually, as long as the view is in focus:

public class VulkanSurfaceView : MTKView, IVulkanAppHost
{
    ...

    public override void Draw()
    {
        Renderer.Tick();
        base.Draw();
    }
}

However, on Android I have to do this, where I call Invalidate() from within the OnDraw method, else it is only called once. I think this code smells a bit, and I am not sure, if this is the "good" way of doing it. Is my solution okay? If not, does anyone have a better idea?

public class VulkanSurfaceView : SurfaceView, ISurfaceHolderCallback, IVulkanAppHost
{
    ...

    protected override void OnDraw(Canvas? canvas)
    {
        Renderer.Tick();
        base.OnDraw(canvas);
        Invalidate();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷你仙 2025-02-03 23:00:30

您是否尝试在您的表面处理方法中调用setWillnotDraw(false)?
请参阅 link

Did you try calling setWillNotDraw(false) in your surfaceCreated method ?
Refer the link

嘿哥们儿 2025-02-03 23:00:30

谢谢@toolmakersteve。

如果已经请求新框架(由简单的bool请求新框架),我创建了一个计时器,在该计时器中我调用Invalidate()。对于任何有兴趣的人,我都这样做:

protected override void OnDraw(Canvas? canvas) // Just to show the updated OnDraw-method
{
    Renderer.Tick();
    base.OnDraw(canvas);
}

public void SurfaceCreated(ISurfaceHolder holder)
{
    TickTimer = new System.Threading.Timer(state =>
    {
        AndroidApplication.SynchronizationContext.Send(_ => { if (NewFrameRequested) Invalidate(); }, state);

        try { TickTimer.Change(0, Timeout.Infinite); } catch (ObjectDisposedException) { }

    }, null, 0, Timeout.Infinite);
}

现在它很简单,但是它可以起作用,并且可能会成长。使用这种方法,我最初的不良帧率的原因是对计时器的“ dueTime”的误解(请参阅 noreflow noreferrer“> timer class ),虽然我是框架。 这实际上是帧之间的时间,现在似乎很明显

正如@bhargavi还提到的那样,您需要设置“ setWillNotDraw(false)”,如果在视图无效时未调用ondraw。

Thank you to @ToolmakerSteve.

I created a Timer where I call Invalidate() if a new frame has been requested (by me via a simple bool). For anyone interested I do it like so:

protected override void OnDraw(Canvas? canvas) // Just to show the updated OnDraw-method
{
    Renderer.Tick();
    base.OnDraw(canvas);
}

public void SurfaceCreated(ISurfaceHolder holder)
{
    TickTimer = new System.Threading.Timer(state =>
    {
        AndroidApplication.SynchronizationContext.Send(_ => { if (NewFrameRequested) Invalidate(); }, state);

        try { TickTimer.Change(0, Timeout.Infinite); } catch (ObjectDisposedException) { }

    }, null, 0, Timeout.Infinite);
}

For now it is very simple, but it works and will probably grow. The reason for my initial bad framerate with this method was a misunderstanding of the "dueTime" of the Timer (see Timer Class), which I though was the framerate sought. This is actually the time between frames, which seems obvious now.

As @Bhargavi also kindly mentioned you need to set "setWillNotDraw(false)" if OnDraw is not being called when invalidating the view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文