Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAUI Android Shadow function is missing internal View.Context.ToPixels() function to get proper scaling (simple proof included) #17886

Open
jonmdev opened this issue Oct 7, 2023 · 1 comment · May be fixed by #17902
Labels
area-drawing Shapes, Borders, Shadows, Graphics, BoxView, custom drawing platform/android 🤖 t/bug Something isn't working
Milestone

Comments

@jonmdev
Copy link

jonmdev commented Oct 7, 2023

Description

MAUI Android uses Android.Views.View.Context.ToPixels() behind the scenes to scale things to and from the full native resolution and the "MAUI resolution" which seems to be more standardized for sizes based on pixel density I believe.

This however, is missing on the Shadow function which is creating abnormal behavior compared to Windows/iOS which is easy to demonstrate.

Here is a simple demo code to replace App.xaml.cs on a default MAUI project:

    public partial class App : Application {
        public App() {
            InitializeComponent();

            ContentPage mainPage = new();
            MainPage = mainPage;

            VerticalStackLayout vert = new VerticalStackLayout();
            vert.Margin = new Thickness(0, 30);
            mainPage.Content = vert;

            Border border = new Border();
            border.WidthRequest = border.HeightRequest = 200;
            border.StrokeShape = new RoundRectangle() { CornerRadius = 30 };
            border.BackgroundColor = Colors.Bisque;

            vert.Children.Add(border);

            border.HandlerChanged += delegate {
                setShadow(border, new Point(0, 10), 10, Colors.Red);
            };

        }

        public static void setShadow(View viewToSet, Point offset, float radius, Color color) {
            Point offsetScaled = offset;
            float radiusScaled = radius;

#if ANDROID
            bool scalePixels = true;
            if (scalePixels) {
                
                Android.Views.View viewAndroid = ElementExtensions.ToPlatform(viewToSet, viewToSet.Handler.MauiContext);
                offsetScaled.X = viewAndroid.Context.ToPixels(offsetScaled.X);
                offsetScaled.Y = viewAndroid.Context.ToPixels(offsetScaled.Y);
                radiusScaled = viewAndroid.Context.ToPixels(radius);
            }
#endif
            viewToSet.Shadow = new() { Offset = offsetScaled, Radius = radiusScaled, Brush = color };
        }
    }

Here I am using a function to set the Shadow effect that implements the Android ToPixels() function in Android.

This is what the project looks like naturally in Windows:

shadow pixel scaling bug - windows

Here is what it looks like in Android with the scale fix:

shadow pixel scaling bug - android scaled

Here is what it looks like in Android without the scale fix (current MAUI code):

shadow pixel scaling bug - android no scale

You can clearly see the shadow is incredibly tiny without the scale fix because it is not being scaled along with all the other objects on screen. Whereas with the scale fix it matches correctly.

On a point of interest, is there any better way to access the ToPixels function than this? It seems you have to get it from a view which needs a handler, which needs to be added to the hierarchy. Hence accessing it on HandlerChanged. But it is annoying to program it like this. Is there any way to access this function directly inside the public App() function?

Thanks for any thoughts and fixes.

Steps to Reproduce

No response

Link to public reproduction project repository

https://github.com/jonmdev/Shadow-Pixel-Scaling-Bug

Version with bug

7.0.92

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

Android API 33, .NET 7.0, Google Pixel 5 Emulator

Did you find any workaround?

Demo workaround code posted above.

Relevant log output

No response

@jonmdev jonmdev added the t/bug Something isn't working label Oct 7, 2023
@jonmdev jonmdev changed the title Android Shadow function is missing internal View.Context.ToPixels() function to get proper scaling (simple proof included) MAUI Android Shadow function is missing internal View.Context.ToPixels() function to get proper scaling (simple proof included) Oct 7, 2023
@jsuarezruiz jsuarezruiz added area-drawing Shapes, Borders, Shadows, Graphics, BoxView, custom drawing platform/android 🤖 labels Oct 9, 2023
@jsuarezruiz jsuarezruiz added this to the Backlog milestone Oct 9, 2023
@ghost
Copy link

ghost commented Oct 9, 2023

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-drawing Shapes, Borders, Shadows, Graphics, BoxView, custom drawing platform/android 🤖 t/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants