Using Grid with AbsoluteLayout - Xamarin Forms

2

I need to use a Grid screen (to organize the Entries and Buttons) and AbsoluteLayout (to have the ball in the middle of the screen). If this is done the screen layout becomes deformed (image below). If you shoot AbsoluteLayout the screen gets organized as it should.

MyneedistouseGridandAbsoluteLayoutwithouthavingthedeformations.

FollowtheXAMLcode:

<?xmlversion="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FoodSuppy.Login"
             Title="FoodSuppy">
    <AbsoluteLayout>
        <Grid>
            <Grid.RowDefinitions>
                <!-- Define as linhas -->
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <BoxView Grid.Row="0"
                         BackgroundColor="Bisque"/>
            <BoxView Grid.Row="1"
                         BackgroundColor="Accent"/>
            <BoxView Grid.Row="2"
                         BackgroundColor="Aqua"/>
            <BoxView Grid.Row="3"
                         BackgroundColor="Beige"/>
            <BoxView Grid.Row="4"
                         BackgroundColor="Blue"/>

            <!-- Entry's -->
            <Entry Grid.Row="2"
                       x:Name="entryEmail" 
                       Text="[email protected]"
                       FontSize="Small"
                       VerticalOptions="StartAndExpand"/>
            <Entry Grid.Row="2"
                       x:Name="entrySenha" 
                       IsPassword="True"
                       Text="123456"
                       FontSize="Small"
                       VerticalOptions="CenterAndExpand"/>

            <!-- Botões -->
            <Button Grid.Row="3"
                    Text="Cadastro"
                    Clicked="btnCadastrarUserAsync"
                    TextColor="White"
                    HorizontalOptions="Start"
                    VerticalOptions="StartAndExpand"
                    FontSize="Small"
                    BackgroundColor="DodgerBlue"
                    Margin="0"/>
            <Button Grid.Row="3"
                    x:Name="btnAcessar" 
                    Clicked="btnAcessar_Clicked"
                    HorizontalOptions="Center"
                    VerticalOptions="StartAndExpand"
                    Text="Acessar"
                    TextColor="White"
                    FontSize="Small"
                    BackgroundColor="DodgerBlue"
                    Margin="0"/>
            <Button Grid.Row="3"
                    Text="Sair"
                    Clicked="Sair_Clicked"
                    HorizontalOptions="End"
                    VerticalOptions="StartAndExpand"
                    TextColor="White"
                    FontSize="Small"
                    BackgroundColor="DodgerBlue"
                    Margin="0"/>
        </Grid>

        <!-- Loading -->
        <StackLayout IsVisible="{Binding IsLoading}" 
                     AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
                     AbsoluteLayout.LayoutFlags="All"  
                     BackgroundColor="DodgerBlue" 
                     Opacity="0.5">

            <!-- Loading -->
            <ActivityIndicator x:Name="actInd"
                               IsRunning="{Binding IsLoading}"
                               IsVisible="{Binding IsLoading}"
                               Color="DarkBlue"
                               HeightRequest="60"
                               WidthRequest="60"
                               BackgroundColor="Transparent"
                               HorizontalOptions="CenterAndExpand"
                               VerticalOptions="CenterAndExpand">
            </ActivityIndicator>
        </StackLayout>

    </AbsoluteLayout>
</ContentPage>
    
asked by anonymous 29.05.2018 / 22:51

1 answer

2

TL; DR;

You do not need AbsoluteLayout to get the result you want. Only Grid is already able to provide the layout.

Just include the StackLayout that contains the ActivityIndicator at the end of the grid, occupying all lines.

So:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FoodSuppy.Login"
             Title="FoodSuppy">
    <Grid>
        <Grid.RowDefinitions>
            <!-- Define as linhas -->
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- BoxViews -->
        ...

        <!-- Entry's -->
        ...

        <!-- Botões -->
        ...     

        <!-- Loading -->
        <StackLayout Grid.Row="0" Grid.RowSpan="5"
                     VerticalOptions="FillAndExpand"
                     HorizontalOptionsOptions="FillAndExpand"
                     IsVisible="{Binding IsLoading}" 
                     BackgroundColor="DodgerBlue" 
                     Opacity="0.5">
            <!-- Loading -->
            <ActivityIndicator x:Name="actInd"
                               IsRunning="{Binding IsLoading}"
                               IsVisible="{Binding IsLoading}"
                               Color="DarkBlue"
                               HeightRequest="60"
                               WidthRequest="60"
                               HorizontalOptions="Center"
                               VerticalOptions="Center">
            </ActivityIndicator>
        </StackLayout>
    </Grid>
</ContentPage>

About Grid

The secret here is how Grid works. Just like RelativeLyout and AbsoluteLayout Grid supports overlapping views (which is the effect you want).

This overlap is defined by the order in which you declare the elements in XAML : elements at the end of Grid will have a posição Z higher than previous ones, regardless of which row or column they are occupying.

This allows us to create overlapping layouts at will. See this image (with a pseudo perspective), for example:

WecoulduseGridtorepresentitthisway:

<GridBackgroundColor="Silver"
      ColumnSpacing="10"
      RowSpacing="10"
      Padding="20">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <BoxView Grid.Column="0" Grid.Row="0"
         Color="OrangeRed"/>

    <BoxView Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"
         Color="MediumSlateBlue"
         Margin="5,20"/>

    <BoxView Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2"
         Color="Green"
         Margin="10,0"/>

    <BoxView Grid.Column="1" Grid.Row="0" Grid.RowSpan="3"
         Color="Gold"
         Margin="0,25"/>    

    <BoxView Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"
         Color="White"
         Margin="-5"/>

    <BoxView Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Grid.RowSpan="2"
         Color="Black"
         Opacity="0.4"
         Margin="20,30"/>
</Grid>

The result of this is:

Notethatbecauseithasbeendefinedlasttheblackboxisaboveall.ExactlyhowyouneeditwithActivityIndicator.

UsingAbsoluteLayout

Ifyoustillprefertousetheabsolutelayout,youwillneedtosetLayoutBoundsandLayoutFlagstoallelementswithinit.

Inyourcase,XAMLwouldlooklikethis:

<?xmlversion="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FoodSuppy.Login"
             Title="FoodSuppy">
    <AbsoluteLayout>
        <Grid AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
              AbsoluteLayout.LayoutFlags="All">
            <Grid.RowDefinitions>
                <!-- Define as linhas -->
                ...
            </Grid.RowDefinitions>

            <!-- BoxViews -->
            ...

            <!-- Entry's -->
            ...

            <!-- Botões -->
            ...

        </Grid>

        <!-- Loading -->
        <StackLayout IsVisible="{Binding IsLoading}" 
                     AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
                     AbsoluteLayout.LayoutFlags="All"  
                     BackgroundColor="DodgerBlue" 
                     Opacity="0.5">

            <!-- Loading -->
            ...
        </StackLayout>

    </AbsoluteLayout>
</ContentPage>

The same overlay rule applies: The items below in XAML are 'over' the previous

I hope I have helped.

    
30.05.2018 / 00:44