Xamarin Forms Flex Layout大小问题

时间:2019-07-04 08:50:20

标签: xaml layout xamarin.forms

在我的Xamarin Forms应用程序中,我需要在另一个flex布局内放置一个flex布局。这是因为:

  • 我的应用程序中需要有两列-一列占据80%的屏幕,另一列占据20%的屏幕。我将FlexLayout与两个为其设置了FlexLayout.Basis属性的子级一起使用。
  • 在其中一列中,我需要显示一系列视图,以便它们包装以填充可用空间。我使用设置为Wrap的FlexLayout来实现此目的。

在此布局下方,我需要显示其他一些控件。 我的问题是,包含包装控件的FlexLayout不能正确调整其高度,“底部”控件会侵占包装布局。这是问题的一个示例(在Android中): enter image description here

Label11被按钮遮住了。红色边框是Android UI Automator Viewer中FlexLayout的边框。高度似乎并未根据已添加的控件进行调整。 如果我删除了“右按钮”列,因此不需要伸缩基础属性,则它的大小会准确。我认为包含包装的控件的FlexLayout没有考虑到它位于已设置为80%宽度的列中的事实-它似乎以其高度为基础,就好像它占据了屏幕的整个宽度一样。有谁知道解决这个问题的方法吗? 这是重现问题的xaml:

<?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:FlexLayoutProb"
         x:Class="FlexLayoutProb.MainPage">

<StackLayout  HorizontalOptions="FillAndExpand"
              VerticalOptions="FillAndExpand"
              AutomationId="stackLayoutTop">

    <FlexLayout
        AutomationId="FlexLayoutTop"
        HorizontalOptions="FillAndExpand"
        VerticalOptions="Start"
        >

        <StackLayout AutomationId="stackLayoutLeft" FlexLayout.Basis="80%" HorizontalOptions="FillAndExpand" >
            <FlexLayout
        AutomationId="FlexLayoutCtrls"
        HorizontalOptions="FillAndExpand"
        VerticalOptions="Start"
                Wrap="Wrap" BackgroundColor="LightGreen"
        >
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label1"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label2"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label3"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label4"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label5"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label6"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label7"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label8"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label9"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label10"></Label>
                <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label11"></Label>
            </FlexLayout>
        </StackLayout>

        <StackLayout AutomationId="stackLayoutRight" FlexLayout.Basis="20%" HorizontalOptions="FillAndExpand">


            <Button Text="Right Button" HorizontalOptions="FillAndExpand"></Button>

        </StackLayout>

    </FlexLayout>

    <Button Text="Bottom Button"></Button>


</StackLayout>

</ContentPage>

2 个答案:

答案 0 :(得分:0)

解决方案::您可以使用 Grid 代替 FlexLayout

<ScrollView>
  <Grid>
    <Grid.RowDefinitions>
       <RowDefinition Height="90*" />
       <RowDefinition Height="10*" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
       <ColumnDefinition Width="80*" />
       <ColumnDefinition Width="20*" />
    </Grid.ColumnDefinitions>

   <FlexLayout
      Grid.Column="0"
      Grid.Row="0"
      AutomationId="FlexLayoutCtrls"
      HorizontalOptions="FillAndExpand"
      VerticalOptions="Start"
      Wrap="Wrap" 
      BackgroundColor="LightGreen">

     <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label1"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label2"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label3"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label4"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label5"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label6"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label7"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label8"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label9"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label10"></Label>
    <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label11"></Label>
   </FlexLayout>

   <StackLayout Grid.Row="0" Grid.Column="1" HeightRequest="40" AutomationId="stackLayoutRight"  HorizontalOptions="FillAndExpand">

     <Button Text="Right Button" HorizontalOptions="FillAndExpand"></Button>

   </StackLayout>

   <Button  Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Text="Bottom Button"/>
 </Grid>
</ScrollView>

答案 1 :(得分:0)

感谢Harold Harvey帮助我解决了这个问题。这是他的建议:

该问题似乎与发布到Xamarin表单团队的现有错误有关。它目前是开放的,正在调查中。 https://github.com/xamarin/Xamarin.Forms/issues/4875

该错误基本上指出,当布局动态添加/删除子代时,高度变化不会通知父代。因此,作为一种解决方法,我将提供此解决方案

  <?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:FlexLayoutProb"
         x:Class="FlexLayoutProb.MainPage">

<StackLayout  HorizontalOptions="FillAndExpand"
          VerticalOptions="FillAndExpand"
          AutomationId="stackLayoutTop">

<FlexLayout
    AutomationId="FlexLayoutTop"
    HorizontalOptions="FillAndExpand"
    VerticalOptions="Start"
    >

    <StackLayout 
  AutomationId="stackLayoutLeft"
 FlexLayout.Basis="80%"
 HorizontalOptions="FillAndExpand"
 HeightRequest="{Binding Height, Source={x:Reference FlexLayoutCtrls}}">
        <FlexLayout
        x:Name="FlexLayoutCtrls"
    AutomationId="FlexLayoutCtrls"
    HorizontalOptions="FillAndExpand"
    VerticalOptions="Start"
            Wrap="Wrap" BackgroundColor="LightGreen"
    >
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label1"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label2"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label3"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label4"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label5"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label6"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label7"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label8"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label9"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label10"></Label>
            <Label HeightRequest="50" WidthRequest="100" Margin="5" BackgroundColor="LightCyan" Text="Label11"></Label>
        </FlexLayout>
    </StackLayout>

    <StackLayout AutomationId="stackLayoutRight" FlexLayout.Basis="20%" HorizontalOptions="FillAndExpand">


        <Button Text="Right Button" HorizontalOptions="FillAndExpand"></Button>

    </StackLayout>

</FlexLayout>

<Button Text="Bottom Button"></Button>
</StackLayout>
</ContentPage>

新行是:  HeightRequest =“ {Binding Height,Source = {x:Reference FlexLayoutCtrls}}”“ x:Name =“ FlexLayoutCtrls”

我已经在UWP,iOS和Android上对此进行了测试,其行为符合您的预期。 由于FlexLayout的尺寸已正确调整,因此会将正确的高度传递给父StackLayout。