【问题标题】:How to make FlexLayout's height adjust to its content?如何使 FlexLayout 的高度适应其内容?
【发布时间】:2021-02-03 01:07:43
【问题描述】:

在我的 Xamarin Forms 应用程序中,我有一个字符串列表(最少 1 个,最多 4 个),我想在列布局中均匀显示。每列需要具有相同的宽度,并且内容应该扩展,以便整个文本被包裹并且可见。我知道如何使用Grid 控件在其列上使用Width="*" 来做到这一点。

我想使用FlexLayout 获得相同的结果,因此我可以将字符串列表绑定到BindableLayout 并轻松添加和删除列(我不会显示字符串,而是在每列中显示更复杂的布局)。

使用FlexLayout.GrowFlexLayout.Basis 我可以让FlexLayout 显示大小均匀的列。问题是使FlexLayout 的高度适合所有显示的标签。只显示第一行文本。

GridFlexLayout 都包含在 StackLayout 中:

<StackLayout>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Label  Text="First label" Grid.Column="0" BackgroundColor="Aqua"
                LineBreakMode="WordWrap" />

        <Label Text="Second label" Grid.Column="1"  BackgroundColor="Red"
               LineBreakMode="WordWrap" />

        <Label Text="Third label but with longer text" Grid.Column="2" BackgroundColor="Aqua"
               LineBreakMode="WordWrap"/>

        <Label Text="Fourth label" BackgroundColor="Red"
               Grid.Column="3"   LineBreakMode="WordWrap" />

    </Grid>
    <BoxView BackgroundColor="Blue"></BoxView>

    <FlexLayout AlignItems="Stretch">
        <Label  Text="First label" 
                FlexLayout.Grow="1" 
                FlexLayout.Basis="0" 
                BackgroundColor="Aqua"
                LineBreakMode="WordWrap" />

        <Label  Text="Second label" 
                FlexLayout.Grow="1" 
                FlexLayout.Basis="0" 
                BackgroundColor="Red"
                LineBreakMode="WordWrap" />

        <Label  Text="Third label but with longer text" 
                FlexLayout.Grow="1" 
                FlexLayout.Basis="0" 
                BackgroundColor="Aqua"
                VerticalOptions="FillAndExpand"
                LineBreakMode="WordWrap" />

        <Label  Text="Fourth label" 
                FlexLayout.Grow="1" 
                FlexLayout.Basis="0" 
                BackgroundColor="Red"
                LineBreakMode="WordWrap" />

    </FlexLayout>
    <BoxView BackgroundColor="Blue"></BoxView>
</StackLayout>

Grid and FlexLayout displayed

我发现当将 FlexLayoutHeightRequest 设置为特定数字(例如 150)时,一切都按预期工作 - 行的高度为 150,所有标签都伸展以适应该数字。所以我需要以某种方式指定HeightRequest="Auto",以便该行适合所有列的内容而不设置为特定值

有没有办法做到这一点?

【问题讨论】:

  • 您可能需要在FlexLayout中为FlexLayout或Label设置hightRequest,或者只使用Grid,别想其他办法了。
  • 当您已经有了网格解决方案时,为什么还要探索 Flex
  • @ShubhamTyagi 出于我所描述的原因:网格迫使我提前声明所有列 (XAML),或者让我在后面的代码中动态定义所有标记。 FlexLayout 将允许我将 IEnumerable 绑定到 BindableLayout 并通过 DataTempalte 为单个列定义一个模板

标签: xaml xamarin xamarin.forms


【解决方案1】:

FlexLayout 将剪切其子 Elements 。所以在你的情况下使用 Grid 是最好的解决方案。

这样我就可以将字符串列表绑定到 BindableLayout 并轻松添加和删除列

如果你想显示一个数据集合,我建议你可以使用 ListViewCollectionView(如果你想让集合水平滚动或显示多列在同一行)。

 <ContentPage.Resources>
        <ResourceDictionary>
            <local:WidthConverter x:Key="WidthConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout x:Name="stack">
        <CollectionView x:Name="list"  >

            <CollectionView.ItemsLayout>
                <LinearItemsLayout Orientation="Horizontal" />
            </CollectionView.ItemsLayout>

            <CollectionView.ItemTemplate>
                <DataTemplate>
                    

                        <Grid WidthRequest="{Binding Source={x:Reference stack},Path=Width,Converter={StaticResource WidthConverter}}">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>

                            <Label Text="111111" BackgroundColor="LightBlue"  />

                           

                        </Grid>

                    
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

在后面的代码中

public class WidthConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var width = (double)value;

            if(width>0)
            {
                return width * 0.25;
            }

            return 100;

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return 0;
        }
    }

更多详情可以查看https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/layout#horizontal-list

【讨论】:

  • 这几乎就是我想要的。我尝试使用集合视图,但不知道如何让它在一行中显示绑定的项目,所有 dataTemplates 具有相同的宽度(如提供的屏幕截图所示)。向 itemSource 添加项目需要在视图中添加列,而不是行。
  • 查看我的更新答案。如果回复有帮助,请采纳为答案(点击此答案左上角的“✔”),对有类似问题的其他人有帮助跨度>
  • 这会使集合视图为 itemSource 中的每个项目添加一列,但不会使它们的宽度与我为每个项目添加独立网格控件的宽度相同。有没有办法让我在 itemSource 中有 4 个项目时,每个 dataTemplate 将占用相等 (25%) 的宽度?
猜你喜欢
  • 1970-01-01
  • 2014-09-04
  • 2021-08-04
  • 2011-06-11
  • 2011-07-16
  • 2019-11-24
  • 1970-01-01
  • 2016-05-12
相关资源
最近更新 更多