17

I have a login page using a StackLayout for the content (username, password, login button). After the user clicks the login button, I want a "loading" block set in the absolute center of the page, on top of the existing StackLayout content. For some annoying reason, this is not straightforward. It seems like a simple, common thing to do - how is this done?

David Jesus
  • 1,981
  • 2
  • 29
  • 34
jbyrd
  • 5,287
  • 7
  • 52
  • 86

2 Answers2

26

You used a right tag: AbsoluteLayout.


var loadingView = new StackLayout
{
    Padding = 6,
    Orientation = StackOrientation.Horizontal,
    BackgroundColor = Color.Gray,
    Children =
    {
        new ActivityIndicator
        {
            Color = Color.White,
            IsRunning = true,
            VerticalOptions = LayoutOptions.Center,
            WidthRequest = 20,
            HeightRequest = 20
        },
        new Label 
        {
            TextColor = Color.White,
            Text = "Loading...",
            VerticalOptions = LayoutOptions.Center
        }
    }
};

var layout = new AbsoluteLayout
{
    Padding = 0,
    HorizontalOptions = LayoutOptions.FillAndExpand,
    VerticalOptions = LayoutOptions.FillAndExpand,
    Children =
    {
        {
            new BoxView {Color = Color.Green}, 
            new Rectangle(0, 0, 1, 1), 
            AbsoluteLayoutFlags.All
        },
        {
            loadingView, 
            new Rectangle(0.5, 0.5, -1, -1), 
            AbsoluteLayoutFlags.PositionProportional
        }
    }
};

Or 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" x:Class="ArtiSO.LoadingPage">
    <ContentPage.Content>
        <AbsoluteLayout Padding="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <BoxView Color="Lime" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" />
            <StackLayout Padding="6" Orientation="Horizontal" BackgroundColor="Gray" AbsoluteLayout.LayoutBounds="0.5, 0.5, -1, -1" AbsoluteLayout.LayoutFlags="PositionProportional">
                <ActivityIndicator Color="White" IsRunning="true" VerticalOptions="Center" WidthRequest="20" HeightRequest="20" />
                <Label TextColor="White" Text="Loading..." VerticalOptions="Center" />
            </StackLayout>
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage>

Result:

Preview

Mikalai Daronin
  • 8,590
  • 2
  • 35
  • 47
  • 1
    Is there a way to do it without making the topmost layer an AbsoluteLayout? B/c now that affects the main content I want in there. For example, if the main content inside the AbsoluteLayout is a StackLayout, I can't center it by setting the VerticalOptions and HorizontalOptions to Layout.Center (b/c those properties won't have any affect; I would have to set layout bounds and layout flags when adding the stack layout to the absolute layout). – jbyrd Mar 24 '16 at 12:48
  • I'm no sure that I understand you correctly. If you want to center a child in an AbsoluteLayout, you can do it providing "bounds" and "flags" parameters: https://gist.github.com/lassana/effb87970c54f2097c0f – Mikalai Daronin Mar 24 '16 at 14:08
  • 1
    As per jbyrd's comment, the question describes a page that already contains a StackLayout - which is *not* to be centered. *Then* a page-centered element is to be overlaid. This answer doesn't say how to center something, while retaining the existing non-centered StackLayout. A fix is to make top-level a one-cell Grid, containing both the original StackLayout and the added AbsoluteLayout - overlaid in the same cell. Similar to David's answer (but using an AbsoluteLayout). – ToolmakerSteve Apr 14 '22 at 18:09
8

To center an ActivityIndicator maybe you can try this Grid tip:

<ContentPage.Content>
    <Grid>
        <StackLayout>
            <Label Text="All content view in this StackLayout :D" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" />
        </StackLayout>
        <ActivityIndicator
            Color="#006699"
            HorizontalOptions="CenterAndExpand"
            VerticalOptions="CenterAndExpand"
            IsVisible="True"
            IsRunning="True" />
    </Grid>
</ContentPage.Content>

enter image description here


There is a good sample project that looks like this:

enter image description here enter image description here

David Jesus
  • 1,981
  • 2
  • 29
  • 34
  • You can get a good sample in this post. https://xamaritano.data.blog/2020/01/23/centrar-activity-indicator-en-una-vista-de-xamarin-forms/ – David Jesus Jan 30 '20 at 00:46