Bug 45153 - Not possible to create a Grid inside a ScrollView that fills the Screen completely
Summary: Not possible to create a Grid inside a ScrollView that fills the Screen compl...
Status: RESOLVED ANSWERED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: 2.3.2
Hardware: PC Windows
: Normal normal
Target Milestone: ---
Assignee: E.Z. Hart [MSFT]
URL:
Depends on:
Blocks:
 
Reported: 2016-10-07 09:18 UTC by thomas
Modified: 2017-06-26 10:41 UTC (History)
8 users (show)

Tags: ac
Is this bug a regression?: ---
Last known good build:


Attachments
Sample of issue difference between platforms (566.41 KB, image/png)
2016-10-13 19:54 UTC, James
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description thomas 2016-10-07 09:18:13 UTC
After trying for more than two day I surrender. All I want to achieve is a ScrollView with a Grid of 2x3 Images so that the images use the maximum available space while keeping their aspect ratio.


    <ScrollView Orientation="Vertical">



      <Grid  ColumnSpacing="5" RowSpacing="2" >
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="5"/>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="0"/>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="5"/>
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition Height="Auto"/>
          <RowDefinition Height="Auto"/>

        </Grid.RowDefinitions>

        <Image Source="red.jpg"  Aspect="AspectFit" Grid.Column="1" Grid.Row="0"/>
        <Image Source="blue.jpg" Aspect="AspectFit" Grid.Column="3" Grid.Row="0"  />
        <Image Source="green.jpg" Aspect="AspectFit" Grid.Column="1" Grid.Row="1" />
        <Image Source="brown.jpg" Aspect="AspectFit" Grid.Column="3" Grid.Row="1" />
        <Image Source="purple.jpg" Aspect="AspectFit" Grid.Column="1" Grid.Row="2"  />
        <Image Source="yellow.jpg" Aspect="AspectFit" Grid.Column="3" Grid.Row="2"  />

      </Grid>
    </ScrollView>


But when trying that I get huge Gaps between the Rows.
I think what I want to achieve is so basic that it should not be so difficult or it must be a bug. Several other XF specialists tried their luck with different parameter combinations but got to the same conclusion.

I put a reproproject on github https://github.com/escamoteur/ImageGridTest
Comment 1 Matthew Regul 2016-10-07 21:06:15 UTC
Hi Thomas,

I was wondering if you were trying to achieve a grid like the following...

XX
XX
XX

or

XXX
XXX

=================================================

Here is a modified version of your code, is this what you wanted?

Screencast
 - https://dl.dropboxusercontent.com/u/62849286/Bugs/45153/sample.gif

Formatted Gist version
- https://gist.github.com/mattregul/cd74fd4cc6173d4bec3cd7138044f226

Extra References
- Xamarin Forms - Grids
-- https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/grid/

- Optimizing App Performance with Xamarin.Forms
-- https://www.youtube.com/watch?v=RZvdql3Ev0E


=================================================
=================================================
=================================================


<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:JistTV;assembly=JistTV" xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" x:Class="ImageGridTest.GridPage" Title="Grid" BackgroundColor="Black">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" WinPhone="20,20,20,20" />
</ContentPage.Padding>
<ContentPage.Content>

<ScrollView Orientation="Vertical" BackgroundColor="Teal">
<!--https://www.youtube.com/watch?v=RZvdql3Ev0E-->
<Grid ColumnSpacing="5" RowSpacing="2">

<!--Rows ===================================================-->
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<!--Columns ================================================-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>


<Image Source="red.jpg" Aspect="AspectFit" Grid.Row="0" Grid.Column="0" />
<Image Source="blue.jpg" Aspect="AspectFit" Grid.Row="0" Grid.Column="1" /> 

<Image Source="green.jpg" Aspect="AspectFit" Grid.Row="1" Grid.Column="0" />
<Image Source="brown.jpg" Aspect="AspectFit" Grid.Row="1" Grid.Column="1" />

<Image Source="purple.jpg" Aspect="AspectFit" Grid.Row="2" Grid.Column="0" />
<Image Source="yellow.jpg" Aspect="AspectFit" Grid.Row="2" Grid.Column="1" />
</Grid>
</ScrollView>
</ContentPage.Content>
</ContentPage>
Comment 2 thomas 2016-10-07 21:18:42 UTC
Hi Matthew,

I wanted to achieve:

XX
XX
XX

The screencast you linked is only

X
X
X
X
X
X


Best
Thomas
Comment 3 Matthew Regul 2016-10-07 21:25:42 UTC
Hi Thomas

It is a 2x3, it's just first column is limited to only a size of 5, I thought you wanted that. :) 

If you were to change the size from 5 to *, they will be of equal size.

Although, this does produce a space between each row, let me investigate some more.

Matt
Comment 4 thomas 2016-10-07 21:30:31 UTC
Hi Matt,

yes the first Columns is 5 as sort of margin, but no image is assigned to column 0 or 2

colum 1 could be used to create a defined gap between the two images if necessary. column 4 again is a margin

Best
Thomas
Comment 5 Matthew Regul 2016-10-10 19:12:55 UTC
Thomas,

How about this?

Android Screenshot
- https://cloud.githubusercontent.com/assets/8008527/19247514/8ecb21fa-8ef9-11e6-9ad3-89587b53f24a.png

iOS Screenshot
- https://cloud.githubusercontent.com/assets/8008527/19247536/ab30582e-8ef9-11e6-9a30-854425eefe71.png

Sample Project:
https://dl.dropboxusercontent.com/u/62849286/Bugs/45153/SampleTest2.zip

I set the column's width by...
1) Grabbing the Device's screen width during init
2) Dividing the device width by the number of colum's we'd like to have (2 in this case)
3) Subtract out a little more for padding

TODO:

1) I've only set the code up for Android and iOS, you'll need to code the other project.

2) You may need to rerun this code if the user rotates the screen, or perhaps just detect the orientation and then use DisplayScreenWidth or DisplayScreenHeight depending on the situation. (DisplayScreenWidth when in Portrait)
Comment 6 Matthew Regul 2016-10-10 19:14:25 UTC
Note, that this is more of a workaround... I agree that there seems to be a sizing issue when using * for both grid row and column
Comment 7 thomas 2016-10-10 19:17:20 UTC
Hi Matt,

thanks, that looks good.
Altough as you said this should go automatic. Any comments from the forms devs on this?

Thanks
Thomas
Comment 8 Matthew Regul 2016-10-11 14:47:02 UTC
So, I would was this is a confirmed bug in Xamarin Forms.
Comment 9 adrianknight89 2016-10-12 02:37:20 UTC
AspectFit also means letter boxing. Grid works correctly as in each image takes as much screen space as possible, but AspectFit does not resize the image vertically to fit the huge gap. If you use AspectFill, you'll see what I mean, but AspectFill can cut off parts of images. Fill is even worse.

If you wrap your images in a content view, you can visualize what's going on.

<ContentView BackgroundColor="Gray" Grid.Column="1" Grid.Row="0">
   <Image Source="red.jpg"  Aspect="AspectFit" />
</ContentView>
<ContentView BackgroundColor="Gray" Grid.Column="3" Grid.Row="0" >
   <Image Source="blue.jpg" Aspect="AspectFit"  />
</ContentView>
<ContentView BackgroundColor="Gray" Grid.Column="1" Grid.Row="1">
   <Image Source="green.jpg" Aspect="AspectFit"  />
</ContentView>
<ContentView BackgroundColor="Gray" Grid.Column="3" Grid.Row="1">
   <Image Source="brown.jpg" Aspect="AspectFit"  />
</ContentView>
<ContentView BackgroundColor="Gray" Grid.Column="1" Grid.Row="2">
   <Image Source="purple.jpg" Aspect="AspectFit"   />
</ContentView>
<ContentView BackgroundColor="Gray" Grid.Column="3" Grid.Row="2">
   <Image Source="yellow.jpg" Aspect="AspectFit"   />
</ContentView>

Now change to AspectFill (of course this is not what you want).

There is no way to force images to take up the whole screen while maintaining AspectFit.

Sorry if I misunderstood what you're trying to accomplish.
Comment 10 thomas 2016-10-12 08:03:41 UTC
Hi Adrian,

I don't want to force them to take up the whole screen,  but to take as much space as possible while keeping there Aspect without cropping. And that what AspectFit normally should do.

Best
Thomas
Comment 11 James 2016-10-13 19:54:13 UTC
Created attachment 18030 [details]
Sample of issue difference between platforms
Comment 12 E.Z. Hart [MSFT] 2017-06-01 16:40:10 UTC
Thomas,

What you're trying to do isn't possible with the current layout engine; because the row heights are unconstrained, they are laid out with the actual original height of the image (before the aspect fitting takes place); this effectively means that the image renderer is sized to ([half the width of the screen] X 400) (using the example images from your GitHub project). After that, the image renderer fits the image to that space while preserving the aspect ratio, which results in an image which is much smaller vertically than its container, and thus the vertical gaps.

I agree that this behavior of AspectFit is a bit ... non-intuitive. This is something that we may (and I stress the _may_) address in an upcoming version of XF. 

For now, your best option is probably to use Matthew Regul's solution (pre-calculating the image layout sizes using the screen dimensions). If you're looking for a more automatic solution, you can also use a custom renderer to shrink the renderers down to the actual size of the image after AspectFit has been applied - I created an example branch of your GitHub repo to demonstrate: 

https://github.com/hartez/ImageGridTest/tree/CustomRenderers 

That solution *does* require an extra layout pass, so there may be a performance hit when using it.
Comment 13 thomas 2017-06-26 10:41:21 UTC
Thanks for clarification