Xamarin.Forms icon indicating copy to clipboard operation
Xamarin.Forms copied to clipboard

FlexLayout height not rendered correctly when placed inside Grid

Open xyfoo opened this issue 6 years ago • 31 comments

Description

FlexLayout (without explicit HeightRequest) placed inside a Grid's Row (Height="Auto"), the FlexLayout will be rendered as the same height as the Grid.

Observation

  • Flexlayout with explicit ```HeightRequest``. Grid render correctly.
  • Swap out FlexLayout with other controls. Grid render correctly.
  • FlexLayout without explicit HeightRequest inside a StackLayout. Render correctly.

Steps to Reproduce

  1. Create a new Forms project and update to v 3.5.0.129452
  2. Add the following
    <Grid x:Name="grid" RowSpacing="0">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <BoxView Grid.Row="0" BackgroundColor="Red" VerticalOptions="FillAndExpand"/>
        <FlexLayout x:Name="flex" Grid.Row="1" BackgroundColor="Yellow">
            <Button Text="Check Height" Clicked="CheckHeight_Clicked" HeightRequest="40" />
        </FlexLayout>
        <BoxView Grid.Row="2" BackgroundColor="Green" VerticalOptions="FillAndExpand"/>
    </Grid>
    
  3. Run the app

Expected Behavior

  • FlexLayout's height will only be as high as it's content.
  • Red & green colored box view will take up most of the vertical space.

Actual Behavior

  • FlexLayout covered the whole page.

Basic Information

  • Tested on: Simulator & device
  • Version with issue: From 3.0.0.446417 to 3.5.129452
  • Last known good version: None.
  • IDE: VS 2017 Enterprise v15.9.6
  • Platform Target Frameworks:
    • iOS: 12.1
    • Android: 8.1
  • Android Support Library Version:: 28.0.0.1
  • Xamarin: 4.12.3.79
  • Xamarin.Android SDK: 9.1.5.0
  • Xamarin.iOS and Xamarin.Mac SDK: 12.2.1.12

Screenshots

bug

Actual behavior vs Expected behavior

Reproduction Link

xfbug.zip

xyfoo avatar Feb 15 '19 05:02 xyfoo

Also tested against the latest 4.0-pre

pauldipietro avatar Feb 21 '19 20:02 pauldipietro

I believe I'm seeing the same issue on UWP.

nbevans avatar Mar 26 '19 16:03 nbevans

https://github.com/xamarin/Xamarin.Forms/blob/50dbbcf55d71f75fa79aa87e8514799b322f3bda/Xamarin.Forms.Core/FlexLayout.cs#L401

Likely caused by this.

nbevans avatar Mar 26 '19 17:03 nbevans

I created this (F#) workaround which sort of fixes the issue for me - though it's not perfect, it is bit glitchy when resizing the UWP window.

Something is really wrong with that OnMeasure method in the core implementation of XF.

type FlexLayout_HackFix20190326() =
    inherit FlexLayout()

    override self.OnMeasure(widthConstraint, heightConstraint) =
        let height = self.Children |> Seq.map (fun c -> c.Measure(Double.PositiveInfinity, Double.PositiveInfinity).Request.Height + c.Bounds.Top) |> Seq.maxBy id
        base.OnMeasure(widthConstraint, height)

nbevans avatar Mar 26 '19 18:03 nbevans

Will this ever be fixed? It basically makes FlexLayout unusable. My "fix" above isn't really good enough - it's too glitchy for production use.

nbevans avatar Jun 04 '19 09:06 nbevans

The same for me

rotorgames avatar Jun 09 '19 11:06 rotorgames

Same here. I'm temporary wrapping the FlexLayout inside a StackLayout until this issue is solved.

DoubleDBE avatar Jun 12 '19 13:06 DoubleDBE

@DoubleDBE Wrapping StackLayout can help. Also, we can get the same behavior as StackLayout if we override OnMeasure in FlexLayout and change widthConstrain or heigthContrain to double.PositinInfinity. But FlexLayout calculates the size of elements inside incorrectly. For example, when I put Label with long text, Grow = 0.5 and WordWrap inside FlexLayout I got incorrect label height and the text was cut.

rotorgames avatar Jun 13 '19 14:06 rotorgames

Just ran into this issue with a FlexLayout out inside my ViewCell. Wrapping in StackLayout as a work around helped.

acastr7 avatar Aug 20 '19 15:08 acastr7

Same problem, here is an example where the FlexLayout should be aligned at the beginning at the top but it takes all the space horizontally and vertically.

    <Grid
        BackgroundColor="Yellow"
        HorizontalOptions="Start"
        VerticalOptions="Start">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <FlexLayout
            AlignContent="Start"
            AlignItems="Start"
            AlignSelf="Start"
            BackgroundColor="Blue"
            Direction="Row"
            HorizontalOptions="Start"
            JustifyContent="Start"
            VerticalOptions="Start">
            <Label
                BackgroundColor="Red"
                FlexLayout.Basis="100"
                FlexLayout.Grow="0"
                HorizontalOptions="Start"
                HorizontalTextAlignment="Start"
                Text="Content1"
                WidthRequest="100" />
            <Label
                BackgroundColor="Orange"
                FlexLayout.Basis="100"
                FlexLayout.Grow="0"
                HorizontalOptions="Start"
                HorizontalTextAlignment="Start"
                Text="Content2"
                WidthRequest="100" />
        </FlexLayout>
    </Grid>

YZahringer avatar Oct 27 '19 18:10 YZahringer

Can also be reproduced in the official samples (see the Experiment page): https://github.com/xamarin/xamarin-forms-samples/tree/master/UserInterface/FlexLayoutDemos

JasonLooney avatar May 02 '20 21:05 JasonLooney

Same here working with XF4.7, is anybody working on this problem?

ChrisTTian667 avatar Aug 06 '20 07:08 ChrisTTian667

Same problem but I'm within an AbsoluteLayout, maybe related (https://forums.xamarin.com/discussion/184860/problem-with-a-scrollview-having-a-flexlayout-inside-absolutelayout#latest).

It looks as if the extra height added to my ScrollView is related to the height it would take if the FlexLayout was a simple StackLayout and no wrapping would be done with the content.

I tried as suggested to wrap my FlexLayout into an(other) StackLayout but it does not help.

@nbevans My mobile app will obviously not "resize" (maybe change orientation but I could possibly live with that). Is your hack somehow to be implemented for both iOS and Android somehow? Custom renderer? Mind providing the code?

xperseguers avatar Sep 09 '20 07:09 xperseguers

Same here. I'm temporarily wrapping the FlexLayout inside a StackLayout until this issue is solved.

Yes, exactly, I am facing this issue yet so I have wrapped FlexLayout with StackLayout, and it works fine.

<StackLayout Grid.Row="0" HorizontalOptions="FillAndExpand" Padding="10" VerticalOptions="Start">
    <FlexLayout BackgroundColor="Green" HorizontalOptions="FillAndExpand" VerticalOptions="Start" BindableLayout.ItemsSource="{Binding ItemCollection}"
            Direction="Row" Wrap="Wrap" JustifyContent="Start" AlignContent="Start" Margin="0" Padding="0">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <pancake:PancakeView BackgroundColor="Blue"
                    HasShadow="False" IsClippedToBounds="True" Padding="5" Margin="5"
                    CornerRadius="10" HeightRequest="30" HorizontalOptions="Start" VerticalOptions="Start">
                    <Label Text="{Binding Title}" TextColor="White" HorizontalOptions="Center"
                        VerticalOptions="Center" HorizontalTextAlignment="Center"
                        VerticalTextAlignment="Center" />
                </pancake:PancakeView>
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </FlexLayout>
</StackLayout> 

divyesh008 avatar Sep 18 '20 11:09 divyesh008

FYI: Having placed the Flexlayout inside a Stacklayout which is placed inside two nested Grids triggers a NullReferenceException in LayoutSubviews().. Removing the uppermost Grid resolves this.

what3var avatar Sep 25 '20 12:09 what3var

Hi, any news? I'm going to forms 5.0 and this problem persist.

thanks

carbonete avatar Feb 04 '21 18:02 carbonete

Same here. I'm temporarily wrapping the FlexLayout inside a StackLayout until this issue is solved.

Yes, exactly, I am facing this issue yet so I have wrapped FlexLayout with StackLayout, and it works fine.

<StackLayout Grid.Row="0" HorizontalOptions="FillAndExpand" Padding="10" VerticalOptions="Start">
    <FlexLayout BackgroundColor="Green" HorizontalOptions="FillAndExpand" VerticalOptions="Start" BindableLayout.ItemsSource="{Binding ItemCollection}"
            Direction="Row" Wrap="Wrap" JustifyContent="Start" AlignContent="Start" Margin="0" Padding="0">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <pancake:PancakeView BackgroundColor="Blue"
                    HasShadow="False" IsClippedToBounds="True" Padding="5" Margin="5"
                    CornerRadius="10" HeightRequest="30" HorizontalOptions="Start" VerticalOptions="Start">
                    <Label Text="{Binding Title}" TextColor="White" HorizontalOptions="Center"
                        VerticalOptions="Center" HorizontalTextAlignment="Center"
                        VerticalTextAlignment="Center" />
                </pancake:PancakeView>
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </FlexLayout>
</StackLayout> 

Thanks this work

carbonete avatar Feb 04 '21 18:02 carbonete

Can we please have some feedback on if/when this problem is going to be solved? Since there is no true MinimumWidthRequest, the only option is to wrap buttons (and other things) in FlexLayout to get the desired behavior but having to wrap the flexlayout in a stacklayout means yet another needless layer between...

Some answers on whether this will be fixed would be highly appreciated. Thank you.

to get the desired behavior

Scratch that. This doesn't work either, because the greedy space behavior of FlexLayout goes both ways making this not work either. Back to the drawing board then I guess.

mlyrstad avatar Feb 25 '21 11:02 mlyrstad

Same issue is for me too. is there any news about that?

kerberosargos avatar Mar 06 '21 20:03 kerberosargos

Hello 2021??? I n my case even wrapping around stack layout doesn't seem to work!!!

azrinsani avatar May 08 '21 00:05 azrinsani

Any news on this?!

Softtinn avatar May 25 '21 14:05 Softtinn

Any update?

kerberosargos avatar May 25 '21 19:05 kerberosargos

We can not use FlexLayout because of this bug. How to solve this issue? Please someone interested in this bug.

kerberosargos avatar Jun 21 '21 23:06 kerberosargos

I created this (F#) workaround which sort of fixes the issue for me - though it's not perfect, it is bit glitchy when resizing the UWP window.

Something is really wrong with that OnMeasure method in the core implementation of XF.

type FlexLayout_HackFix20190326() =
    inherit FlexLayout()

    override self.OnMeasure(widthConstraint, heightConstraint) =
        let height = self.Children |> Seq.map (fun c -> c.Measure(Double.PositiveInfinity, Double.PositiveInfinity).Request.Height + c.Bounds.Top) |> Seq.maxBy id
        base.OnMeasure(widthConstraint, height)

Hello is there any C# implementation?

kerberosargos avatar Jun 21 '21 23:06 kerberosargos

@samhouts What is the problem about this bug?

kerberosargos avatar Jun 21 '21 23:06 kerberosargos

It's 2021, WILL THIS PROBLEM LAST IN MAUI ?

chaoyebugao avatar Nov 04 '21 11:11 chaoyebugao

@ryanharding Be prepared for same-shit-different-shit in Flutter. Last time I checked it out they were still faffing about trying to make textual word wrap and ellipsis work properly on all platforms.

nbevans avatar Nov 16 '21 10:11 nbevans

it works fine to me this my XAML code

data template

<DataTemplate x:Key="templateChartPercent">
        <controllers:ChartPercent
            Title="{helper:Translate PaymentMethode}"
            Margin="7"
            FlexLayout.AlignSelf="Center" />
    </DataTemplate>

FlexLayout

<FlexLayout
                        x:Name="lstChart"
                        BindableLayout.ItemTemplate="{StaticResource templateChartStatic}"
                        Style="{StaticResource FLBase}" />

style

 <Style
            x:Key="FLBase"
            TargetType="FlexLayout">
            <Setter Property="AlignContent" Value="Start" />
            <Setter Property="AlignItems" Value="Start" />
            <Setter Property="Direction" Value="Row" />
            <Setter Property="HorizontalOptions" Value="FillAndExpand" />
            <Setter Property="JustifyContent" Value="SpaceBetween" />
            <Setter Property="VerticalOptions" Value="Start" />
            <Setter Property="Wrap" Value="Wrap" />
        </Style>

KevinAnass avatar Jan 17 '22 10:01 KevinAnass

Feb 2022, the issue is still there... Will this ever be fixed? The issue is more than 2years old...

nZeus avatar Feb 25 '22 12:02 nZeus

March-2022 nd still no fix? =(

wagenheimer avatar Mar 29 '22 13:03 wagenheimer