Проблема с размером макета Xamarin Forms Flex - PullRequest
0 голосов
/ 04 июля 2019

В моем приложении Xamarin Forms мне нужно иметь гибкий макет внутри другого гибкого макета. Это потому что:

  • Мне нужно, чтобы в моем приложении было два столбца - один занимал 80% экрана, а другой занимал 20% экрана. Я использую FlexLayout с двумя детьми, для которых установлено свойство FlexLayout.Basis.
  • В одном из столбцов мне нужно отобразить серию представлений, чтобы они обернулись, чтобы заполнить доступное пространство. Для этого я использую FlexLayout, установленный на Wrap.

Под этим макетом мне нужно отобразить некоторые другие элементы управления. Моя проблема заключается в том, что FlexLayout, содержащий обернутые элементы управления, не корректно регулирует его высоту, а «нижние» элементы управления посягают на обернутый макет. Это пример проблемы (в Android): enter image description here

Метка 11 скрыта кнопкой. Красная граница - это граница FlexLayout в средстве просмотра Android UI Automator. Высота, по-видимому, не регулируется в соответствии с добавленными элементами управления. Если я удаляю столбец «Правая кнопка» и, следовательно, не нуждаюсь в свойствах гибкого базиса, он точно определяет размеры. Я думаю, что 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 голосов
/ 18 июля 2019

Спасибо Гарольду Харви, который помог мне решить эту проблему.Вот что он предложил:

Похоже, что эта проблема связана с существующей ошибкой, опубликованной командой форм 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.

0 голосов
/ 12 июля 2019

Решение: Вы можете использовать Сетка вместо 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>
...