Xamarin Forms Fill Width of Image with Related Aspect

Here is xaml (image in stacklayout). Everything is logical: I installed Aspect for AspectFit and HorizontalOptions in FillAndExpand. The width of the image should fill the width of the stacklayout. The height must be calculated for the Aspect image.

<Image BackgroundColor="Fuchsia" Aspect="AspectFit" Source="{Binding GroupLogo}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/> 

It fills the width, but does not want to draw the full width of the image. Why?

enter image description here

+14
source share
8 answers

AspectFit does what it says on tin, it will put the whole image in the view, which can leave parts of the view blank. Straight from the Xamarin documentation:

Scale the image to fit the view. Some parts may be empty (letter box).

What you are looking for is AspectFill , which scales the image according to:

Scale the image to fill the view. Some parts may be cropped to fill the view.

If you are trying to get the image representation as the image height, I would suggest adding HeightRequest to the image height. In my opinion, image controls, in my experience, don't automatically scale in Xamarin, as the built-in controls also don't support this by default.

Link

+15
source

I had a similar problem. I wanted to fill the width and height of the StackLayout whenever possible, but without cropping the actual image. The answers here helped me find the right way. Here is what worked for me:

  <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" > <Image x:Name="photo" Aspect="AspectFit" /> </Grid> 

Perhaps this will be useful for someone.

Clarification:

HorizontalOptions and VerticalOptions are FillAndExpand, so the height and width of the grid are adjusted to fill the parent, in this case it is Stacklayout. The image is a child of the grid, so it is converted according to the parent (we did not provide any additional parameters to the image).

The aspect of the image is set to AspectFit, so that the image will correspond to the view (in this case, the Grid), as well as preserve its relationship.

Thus, if the image is in portrait mode, but too narrow, it fills the height of the grid (StackLayout), but does not fill the width in order to maintain its relationship and not be cropped from above or below.

If the image is in landscape mode, it fills the width of the grid (StackLayout), but does not fill the height in order to preserve its relationship and not be clipped to the left or right.

+7
source

How I did not find a working example. This works great for me:

 <Grid VerticalOptions="FillAndExpand"> <Image Source="{Binding MyImageSrc}" Aspect="AspectFill" /> </Grid> 
+6
source

Aspect = "AspectFit" is used to place your image inside the layout, it can leave space if the images are small. Aspect = "AspectFill" is used to place your image inside the layout, and it will stretch your image to occupy all the space and leave no space, or your image will be small compared to your parent layout space. Therefore, you should use AspectFill instead of AspectFit.

+3
source

Try to include the image inside the grid, for example:

 <grid> <image></image> </grid> 

Sometimes, when I have an image that does not change correctly, including it in the grid solves the problem.

+1
source

Try using CachedImage from FFImageLoading NuGet Package

Mypage.xaml

 <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="0"> <ff:CachedImage Source="{Binding GroupLogo}" HorizontalOptions="Fill" VerticalOptions="Fill" Aspect="Fill" DownsampleToViewSize="True"/> </StackLayout> 

This will cause the image to try to horizontally fill the container and automatically generate the width while maintaining its aspect.

Add this line of code to MainActivity.xaml after global::Xamarin.Forms.Forms.Init(this, bundle);

 CachedImageRenderer.Init(true); 

An example can be found here.

+1
source

the heightrequest of the stacklayout must be either StartAndExpand, or FillAndExpand or EndAndExpand to automatically adjust the height

0
source

This requires custom rendering for both platforms. Create a FillScreenImageRenderer that inherits from ImageRenderer.

 <local:FillScreenImage Source="{ImageSource}"></local:FillScreenImage> 

The code below stretches to full screen. You can customize the boundaries of the view so that they fit anywhere, for example, in your case, this is the parent view.

IOS:

  protected override void OnElementChanged(ElementChangedEventArgs<Image> e) { base.OnElementChanged(e); UIGraphics.BeginImageContext(UIScreen.MainScreen.Bounds.Size); Control.Image.Draw(UIScreen.MainScreen.Bounds); var dest = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); Control.Image = dest; } 

Android:

  protected override void OnElementChanged(ElementChangedEventArgs<Image> e) { base.OnElementChanged(e); var display = ((Activity)Context).WindowManager.DefaultDisplay; var b = ((BitmapDrawable)Control.Drawable).Bitmap; Bitmap bitmapResized = Bitmap.CreateScaledBitmap(b, display.Width, display.Height, false); Control.SetImageDrawable(new BitmapDrawable(Resources, bitmapResized)); } 
0
source

Source: https://habr.com/ru/post/1013636/


All Articles