#21699·Avalonia

InvalidateVisual() doesn't provoke a repaint in Avalonia 12 under Android

Author: pjt33Created Jul 3, 2026Updated Sep 16, 2026
Labelsbugregressionos-android

Describe the bug

With Avalonia 11, InvalidateVisual() in a custom subclass of Control provokes the rendering system to repaint the control. I rely on this behaviour for my game engine, which has a standard loop of updating the physics and then repainting.

With Avalonia 12 this still works under Windows but not under Android.

To Reproduce

I have created a minimal reproducible demo, starting from the VS template, which is available at https://github.com/pjt33/InvalidateVisualDemo/ . The core of the demo is MinimalCanvas:

    public MinimalCanvas()
    {
        _OnTimer += _GameLoop;
        _Timer = new DispatcherTimer(TimeSpan.FromSeconds(1d / 50), DispatcherPriority.Render, _OnTimer);
    }

    private readonly DispatcherTimer _Timer;
    private readonly EventHandler _OnTimer;

    private float _Theta;

    private void _GameLoop(object? sender, EventArgs e)
    {
        // Update physics
        _Theta += 0.1f;
        if (_Theta > MathF.Tau) _Theta -= MathF.Tau;

        // Provoke redraw
        InvalidateVisual();
    }

The repository includes Desktop and Android applications.

To run with Avalonia 11 you can edit the top-level Directory.Build.props to comment out the second PropertyGroup and uncomment the third one.

Expected behavior

When the Desktop application is executed, the custom control draws a circle segment in an animation which runs from empty to a full circle and then loops. I expected the same to happen under Android, but it paints once and then doesn't repaint.

Avalonia version

12.0.5

OS

Android

Additional context

No response