KEMBAR78
[Android] GraphicsView draws at half size after canvas.ResetState() (issue appears on second Draw) · Issue #31182 · dotnet/maui · GitHub
Skip to content

[Android] GraphicsView draws at half size after canvas.ResetState() (issue appears on second Draw) #31182

@softlion

Description

@softlion

Description

On Android, calling canvas.ResetState() inside a custom GraphicsView (IDrawable) appears to clear the platform scaling, so subsequent draws render at half width and half height on a device with density > 1. The problem doesn’t show on the first Draw, but starts on the second Draw call (e.g., after an Invalidate()), which suggests the scaling info is lost/reset.

Steps to Reproduce

// SomeView.cs
public class SomeView : GraphicsView, IDrawable
{
    public SomeView()
    {
        Drawable = this;

        // Force a second Draw shortly after the first to expose the bug
        Loaded += (_, __) =>
        {
            Microsoft.Maui.Controls.Device.StartTimer(
                TimeSpan.FromMilliseconds(50),
                () => { Invalidate(); return false; } // one-shot
            );
        };
    }

    public void Draw(ICanvas canvas, RectF dirtyRect)
    {
        canvas.ResetState();                 // <-- culprit
        canvas.FillColor = Colors.Yellow;
        canvas.FillRectangle(dirtyRect);     // On 2nd Draw: only half width/height is painted
    }
}
<!-- Usage in a page -->
<Grid WidthRequest="200" HeightRequest="200" BackgroundColor="Red">
    <local:SomeView WidthRequest="200" HeightRequest="200" />
</Grid>

Steps to reproduce

  • Add the SomeView above to a page (Android).
  • Run the app. The first draw looks correct (yellow over red).
  • The timer triggers Invalidate() → second Draw happens.
  • Now only the top-left quarter of the 200×200 area is filled (i.e., half width & half height on density=2).

Actual behavior

  • After the second Draw, content is rendered at half size (as if density scaling were removed).
  • Empirically, multiplying coordinates/sizes by DeviceDisplay.Current.MainDisplayInfo.Density restores expected size.
  • Interaction events (StartInteraction, DragInteraction, etc.) appear consistent with MAUI points, so the mismatch seems to stem from ResetState() clearing the canvas scale.

Expected behavior

  • ResetState() should not drop the device-density scaling that GraphicsView relies on.
  • Drawing calls should continue to use the same coordinate system across successive Draw invocations.

Environment:
.NET MAUI: 9 and 10-preview7
Platform: Android
Device: Android Tablet - simulator - pixel C API28

Notes

Link to public reproduction project repository

No response

Version with bug

10.0.0-preview.7

Is this a regression from previous behavior?

No, this is something new

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

All versions

Did you find any workaround?

Workarounds

  • Avoid calling canvas.ResetState().
  • Or manually reapply scaling after ResetState():
var density = DeviceDisplay.Current.MainDisplayInfo.Density;
canvas.Scale(density);
  • Alternatively, multiply all draw coordinates by density

Relevant log output

Metadata

Metadata

Assignees

Labels

area-drawingShapes, Borders, Shadows, Graphics, BoxView, custom drawingplatform/androids/triagedIssue has been revieweds/verifiedVerified / Reproducible Issue ready for Engineering Triaget/bugSomething isn't working

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions