dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.24k stars 1.76k forks source link

Investigate options for full-size Image loading on Android #8217

Open hartez opened 2 years ago

hartez commented 2 years ago

FlexLayout is not entirely compatible with Glide on Android. The Forms layout engine would, by default, load images at their full size and then scale them. It did this by loading them with no size constraints. Some of the FlexLayout behaviors (notably the sample in the docs at https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/flex-layout#using-flexlayout-for-wrapping-items) relied on this - the (small) images simply loaded at their default size and those dimensions were used to calculate the flex dimensions.

With MAUI.Controls on Windows, this still works. But Android now uses Glide to handle all image loading. And the current Glide loading implementations in PlatformInterop use the default behavior, which never loads the image at its intrinsic size. Rather, it treats those requests as a request to load the image at the device screen dimensions:

[CustomViewTarget] Glide treats LayoutParams.WRAP_CONTENT as a request for an image the size of this device's screen dimensions. If you want to load the original image and are ok with the corresponding memory cost and OOMs (depending on the input size), use .override(Target.SIZE_ORIGINAL). Otherwise, use LayoutParams.MATCH_PARENT, set layout_width and layout_height to fixed dimension, or use .override() with fixed dimensions.

Which breaks the FlexLayout behavior. It does this even if the original image size is smaller than the screen dimensions; small images get scaled up. So instead of the linked example code producing wrapped rows of small images, it produces one screen-wide image per row no matter what size the original images were.

The FlexLayout problems can be mostly worked around by setting explicit widths or heights on the image. But as things stand, the old samples will not work on Android, and Android currently has no way for the user to load a remote image at the full dimensions.

We'll need to evaluate what the best option for loading an image at fill size would be. Making it the default (and adding mappings as in https://github.com/dotnet/maui/issues/8212 to make it easy to improve efficiency) is probably the easiest option from an implementation standpoint. But we may also want to consider adding an "IntrinsicSize" or "FullSize" option to the Aspect property, and simply update the FlexLayout documentation/samples.

ghost commented 2 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

SmartmanApps commented 1 year ago

Hello. I've run into this problem, and despite what the message says, I'm not even trying (intentionally) to load a full size image - in fact I tried various ways to make it smaller - is there any work-around to this? The library I'm trying to get working with Android (works with Windows) is at https://github.com/SmartmanApps/TestImages - I have both the Dropbox svg and the dotnet_bot svg in there. The dotnet_bot svg works on Android, but the Dropbox one does not (it works on Windows, but not Android), and I don't know why - any suggestions?

SmartmanApps commented 1 year ago

Hello again. I've had someone on StackOverflow confirm it worked for them, but it still doesn't work for me. Still don't know why it doesn't work for me. Here is the post https://stackoverflow.com/questions/77166206/having-multiple-issues-getting-images-to-appear-in-a-maui-library