Mobiele apps programmeren met Xamarin – Layout – StackLayout, ScrollView, Frame en BoxView

print

Inhoud


Wat vooraf ging


Welke layouts zijn er?

Xamarin komt met meerdere layouts.

Hoewel u een specifieke layout vaak op meerdere manieren kunt opbouwen zal de ene methode soms meer voor de hand liggen en gemakkelijker zijn om uw doel te bereiken dan de andere methodes. Het is dus belangrijk inzicht te hebben in de verschillende mogelijke manieren om een layout in Xamarin op te bouwen.

We gaan de

in deze post bespreken.

In volgende posten komen

aan bod.

Tenslotte gaan we ook bekijken hoe een layout responsief kan gemaakt worden om in te spelen op de oriëntatie van het toestel.


Layoutopties

Elke Xamarin.Forms View heeft HorizontalOptions en VerticalOptions properties van het type LayoutOptions.

De mogelijke waarden zijn:

  • StartHorizontaal = links van de beschikbare ruimte waarbinnen de View zich bevindt, Verticaal = bovenaan de beschikbare ruimte waarin de View zich bevindt.
  • Center – zowel horizontaal als verticaal wordt de View in de beschikbare ruimte gecentreerd.
  • End – Horizontaal = rechts van de beschikbare ruimte waarbinnen de View zich bevindt, Verticaal = onderaan de beschikbare ruimte waarin de View zich bevindt.
  • FillHorizontaal = neemt de volledige breedte van de beschikbare ruimte waarbinnen de View zich bevindt in, Verticaal = neemt de volledige hoogte van de beschikbare ruimte waarbinnen de View zich bevindt in.

Voorbeelden

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

    <StackLayout Margin="0,20,0,0">
        <Label Text="Start" BackgroundColor="Gray" HorizontalOptions="Start" />
        <Label Text="Center" BackgroundColor="Gray" HorizontalOptions="Center" />
        <Label Text="End" BackgroundColor="Gray" HorizontalOptions="End" />
        <Label Text="Fill" BackgroundColor="Gray" HorizontalOptions="Fill" />
    </StackLayout>

</ContentPage>

Elk van bovenstaande opties heeft ook een Expand-variant waarin de overige beschikbare ruimte wordt opgevuld door de View.

  • StartAndExpand
  • CenterAndExpand
  • EndAndExpand
  • FillAndExpand

Voorbeelden

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

    <StackLayout Margin="0,20,0,0">
        <Label Text="Start" BackgroundColor="Gray" HorizontalOptions="Start" VerticalOptions="StartAndExpand" />
        <Label Text="Center" BackgroundColor="Gray" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
        <Label Text="End" BackgroundColor="Gray" HorizontalOptions="End" VerticalOptions="EndAndExpand" />
        <Label Text="Fill" BackgroundColor="Gray" HorizontalOptions="Fill" VerticalOptions="FillAndExpand"/>
    </StackLayout>

</ContentPage>

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

    <StackLayout Margin="0,20,0,0">
        <Label Text="Start" BackgroundColor="Gray" HorizontalOptions="StartAndExpand" VerticalOptions="End" />
        <Label Text="Center" BackgroundColor="Gray" HorizontalOptions="CenterAndExpand" VerticalOptions="Start" />
        <Label Text="End" BackgroundColor="Gray" HorizontalOptions="EndAndExpand" VerticalOptions="EndAndExpand" />
        <Label Text="Fill" BackgroundColor="Gray" HorizontalOptions="Fill" VerticalOptions="StartAndExpand"/>
    </StackLayout>

</ContentPage>


StackLayout

We hebben reeds vaker kennisgemaakt met de StackLayout. Een StackLayout stapelt de verschillende Views binnen de StackLayout in een horizontale of verticale richting.

Eigenschappen

De 2 belangrijkste eigenschappen zijn:

  • Orientation – De oriëntatie waarin de Views gestapeld worden. Standaard is dit Vertical en deze waarde moet u niet meegeven. Wilt u echter horizontaal stapelen dan moet u deze eigenschap instellen via Orientation="Horizontal".
  • Spacing – Een getal (integer of decimal) dat aangeeft hoeveel ruimte er tussen de verschillende Views moet zijn Spacing="10".

Voorbeeld

Onderstaand voorbeeld stapelt een Button en een aantal BoxViews binnen een StackLayout.

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

    <StackLayout Spacing="10" >
        <Button Text="StackLayout" VerticalOptions="Start" HorizontalOptions="FillAndExpand" />
        <BoxView Color="Yellow" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
        <BoxView Color="Green" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
        <BoxView Color="Blue" VerticalOptions="End" HorizontalOptions="FillAndExpand" />
    </StackLayout>


</ContentPage>

Dezelfde code maar nu in C#.

using Xamarin.Forms;

namespace Layouts
{
    public class StackLayoutPage : ContentPage
    {
        public StackLayoutPage()
        {
            var layout = new StackLayout();
            var button = new Button
            {
                Text = "StackLayout",
                VerticalOptions = LayoutOptions.Start,
                HorizontalOptions = LayoutOptions.FillAndExpand
            };
            var yellowBox = new BoxView
            {
                Color = Color.Yellow,
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand
            };
            var greenBox = new BoxView {
                Color = Color.Green,
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand
            };

            var blueBox = new BoxView
            {
                Color = Color.Blue,
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                HeightRequest = 75
            };

            layout.Children.Add(button);
            layout.Children.Add(yellowBox);
            layout.Children.Add(greenBox);
            layout.Children.Add(blueBox);
            layout.Spacing = 10;
            Content = layout;
        }
    }
}


ScrollView

Standaard kan een StackLayout niet gescrolled worden.

Probeer maar eens onderstaande code uit (voeg eventueel een nieuwe XAML-pagina toe aan het huidige project).

<?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="LayoutOpties.Page1">

    <StackLayout Spacing="20">
        <Label FontSize="Large" HorizontalOptions="Center">1</Label>
        <Label FontSize="Large" HorizontalOptions="Center">2</Label>
        <Label FontSize="Large" HorizontalOptions="Center">3</Label>
        <Label FontSize="Large" HorizontalOptions="Center">4</Label>
        <Label FontSize="Large" HorizontalOptions="Center">5</Label>
        <Label FontSize="Large" HorizontalOptions="Center">6</Label>
        <Label FontSize="Large" HorizontalOptions="Center">7</Label>
        <Label FontSize="Large" HorizontalOptions="Center">8</Label>
        <Label FontSize="Large" HorizontalOptions="Center">9</Label>
        <Label FontSize="Large" HorizontalOptions="Center">10</Label>
        <Label FontSize="Large" HorizontalOptions="Center">11</Label>
        <Label FontSize="Large" HorizontalOptions="Center">12</Label>
        <Label FontSize="Large" HorizontalOptions="Center">13</Label>
        <Label FontSize="Large" HorizontalOptions="Center">14</Label>
        <Label FontSize="Large" HorizontalOptions="Center">15</Label>
        <Label FontSize="Large" HorizontalOptions="Center">16</Label>
        <Label FontSize="Large" HorizontalOptions="Center">17</Label>
        <Label FontSize="Large" HorizontalOptions="Center">18</Label>
        <Label FontSize="Large" HorizontalOptions="Center">19</Label>
        <Label FontSize="Large" HorizontalOptions="Center">20</Label>
    </StackLayout>
    
</ContentPage>

Wellicht krijgt u niet alle labels in beeld en hebt u ook niet de mogelijkheid om te scrollen om de niet-in-beeld-zijnde labels zichtbaar te maken.

De oplossing is eenvoudig, plaats de StackLayout in een ScrollView. De ScrollView is immers een container die andere layouts als content kan hebben en voegt de mogelijkheid van het scrollen toe.

<?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="LayoutOpties.Page1">
    <ScrollView>
        <StackLayout Spacing="20">
            <Label FontSize="Large" HorizontalOptions="Center">1</Label>
            <Label FontSize="Large" HorizontalOptions="Center">2</Label>
            <Label FontSize="Large" HorizontalOptions="Center">3</Label>
            <Label FontSize="Large" HorizontalOptions="Center">4</Label>
            <Label FontSize="Large" HorizontalOptions="Center">5</Label>
            <Label FontSize="Large" HorizontalOptions="Center">6</Label>
            <Label FontSize="Large" HorizontalOptions="Center">7</Label>
            <Label FontSize="Large" HorizontalOptions="Center">8</Label>
            <Label FontSize="Large" HorizontalOptions="Center">9</Label>
            <Label FontSize="Large" HorizontalOptions="Center">10</Label>
            <Label FontSize="Large" HorizontalOptions="Center">11</Label>
            <Label FontSize="Large" HorizontalOptions="Center">12</Label>
            <Label FontSize="Large" HorizontalOptions="Center">13</Label>
            <Label FontSize="Large" HorizontalOptions="Center">14</Label>
            <Label FontSize="Large" HorizontalOptions="Center">15</Label>
            <Label FontSize="Large" HorizontalOptions="Center">16</Label>
            <Label FontSize="Large" HorizontalOptions="Center">17</Label>
            <Label FontSize="Large" HorizontalOptions="Center">18</Label>
            <Label FontSize="Large" HorizontalOptions="Center">19</Label>
            <Label FontSize="Large" HorizontalOptions="Center">20</Label>
        </StackLayout>       
    </ScrollView>
    
</ContentPage>

De ScrollView komt nog met een aantal eigenschappen en methoden die u hier kunt vinden. Maar twee statements will ik er nog even uithalen.

De mogelijkheid om te scrollen naar een vaste positie (hier 150px van de top).

scroll.ScrollToAsync(0, 150, true);

En de mogelijkheid om te scrollen naar een object (hier een Label, met de naam label, dat, na het scrollen, aan de start van het layout-element (naargelang de oriëntatie bovenaan of links)) wordt getoond.

scroll.ScrollToAsync(label, ScrollToPosition.Start, true);

De derde parameter geeft aan dat het scrollen moet geanimeerd zijn.


BoxView en Frame

De BoxView (die we reeds gebruikt hebben) en Frame hebben beide gemeen dat ze een rechthoek weergeven.

Maar daar waar de BoxView de rechthoek enkel opvult met een kleur, kan het frame opgevuld worden met andere content. Het Frame is dan ook afgeleid van ContentView.

BoxView

De BoxView toont een rechthoek in een specifieke kleur en heeft dus de eigenschap Color. De hoogte wordt bepaald door de eigenschap HeightRequest, de breedte wordt bepaald door de eigenschap WidthRequest. Merk op dat het hier gaat om een Request die enkel wordt toegestaan indien de layout het toelaat.

Frame

Het Frame is afgeleid van ContentView en kan dus andere content bevatten.

Het Frame heeft de volgende interessante eigenschappen:

  • HasShadow – een boolean (true of false) die aangeeft of het frame een schaduwrand heeft.
  • OutlineColor – de randkleur
  • CornerRadius – de afronding van de hoeken

Voorbeeld

<?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="LayoutOpties.Page2">

    <StackLayout>
        <BoxView Color="Orange" HeightRequest="40" WidthRequest="40" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"></BoxView>
        <Frame HasShadow="True" OutlineColor="Orange" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
            <Label FontSize="Large">PCVO Dender en Schelde</Label>
        </Frame>
    </StackLayout>
</ContentPage>

Complex voorbeeld in 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="LayoutOpties.Page3">

    <ScrollView>
        <StackLayout Spacing="0" BackgroundColor="Maroon">
            <BoxView HorizontalOptions="FillAndExpand" HeightRequest="20" VerticalOptions="Start" Color="Gray" />
            <Button BorderRadius="30" HeightRequest="60" WidthRequest="60" BackgroundColor="Red" HorizontalOptions="Center" VerticalOptions="Start" />
            <StackLayout HeightRequest="100" VerticalOptions="Start" HorizontalOptions="FillAndExpand" Spacing="20" BackgroundColor="Maroon">
                <Label Text="User Name" FontSize="28" HorizontalOptions="Center" VerticalOptions="Center" FontAttributes="Bold" />
                <Entry Text="Bio + Hashtags" TextColor="White" BackgroundColor="Maroon" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand" />
            </StackLayout>
            <StackLayout Orientation="Horizontal" HeightRequest="50" BackgroundColor="White" Padding="5">
                <StackLayout Spacing="0" BackgroundColor="White" Orientation="Horizontal" HorizontalOptions="Start">
                    <BoxView BackgroundColor="Black" WidthRequest="40" HeightRequest="40" HorizontalOptions="StartAndExpand" VerticalOptions="Center" />
                    <Label FontSize="14" TextColor="Black" Margin="5,0,0,0" Text="Accent Color" HorizontalOptions="StartAndExpand" VerticalOptions="Center" />
                </StackLayout>
                <StackLayout Spacing="0" BackgroundColor="White" Orientation="Horizontal" HorizontalOptions="EndAndExpand">
                    <BoxView BackgroundColor="Maroon" WidthRequest="40" HeightRequest="40" HorizontalOptions="Start" VerticalOptions="Center" />
                    <Label FontSize="14" TextColor="Black" Margin="5,0,0,0" Text="Primary Color" HorizontalOptions="StartAndExpand" VerticalOptions="Center" />
                </StackLayout>
            </StackLayout>
            <StackLayout Orientation="Horizontal" Padding="5">
                <Label FontSize="14" Text="Age:" TextColor="White" HorizontalOptions="Start" VerticalOptions="Center" WidthRequest="100" />
                <Entry HorizontalOptions="FillAndExpand" Text="35" TextColor="White" BackgroundColor="Maroon" />
            </StackLayout>
            <StackLayout Orientation="Horizontal" Padding="5">
                <Label FontSize="14" Text="Interests:" TextColor="White" HorizontalOptions="Start" VerticalOptions="Center" WidthRequest="100" />
                <Entry HorizontalOptions="FillAndExpand" Text="Xamarin.Forms" TextColor="White" BackgroundColor="Maroon" />
            </StackLayout>
            <StackLayout Orientation="Horizontal" Padding="5">
                <Label FontSize="14" Text="Ask me about:" TextColor="White" HorizontalOptions="Start" VerticalOptions="Center" WidthRequest="100"/>
                <Entry HorizontalOptions="FillAndExpand" Text="Xamarin, C#, .NET, Mono..." TextColor="White" BackgroundColor="Maroon" />
            </StackLayout>
        </StackLayout>
    </ScrollView>
    
</ContentPage>

Complex voorbeeld in C#

using Xamarin.Forms;

namespace LayoutOpties
{
    public class Kleurenlijst : ContentPage
    {
        public Kleurenlijst()
        {
            var colors = new[]
            {
                new { value = Color.White, name = "White" },
                new { value = Color.Silver, name = "Silver" },
                new { value = Color.Gray, name = "Gray" },
                new { value = Color.Black, name = "Black" },
                new { value = Color.Red, name = "Red" },
                new { value = Color.Maroon, name = "Maroon" },
                new { value = Color.Yellow, name = "Yellow" },
                new { value = Color.Olive, name = "Olive" },
                new { value = Color.Lime, name = "Lime" },
                new { value = Color.Green, name = "Green" },
                new { value = Color.Aqua, name = "Aqua" },
                new { value = Color.Teal, name = "Teal" },
                new { value = Color.Blue, name = "Blue" },
                new { value = Color.Navy, name = "Navy" },
                new { value = Color.Pink, name = "Pink" },
                new { value = Color.Fuchsia, name = "Fuchsia" },
                new { value = Color.Purple, name = "Purple" }
            };

            StackLayout stackLayout = new StackLayout();

            foreach (var color in colors)
            {
                stackLayout.Children.Add(CreateColorView(color.value, color.name));
            }

            Padding = new Thickness(5, Device.OnPlatform(20, 5, 5), 5, 5);
            Content = new ScrollView
            {
                Content = stackLayout
            };
        }

        View CreateColorView(Color color, string name)
        {
            return new Frame
            {
                OutlineColor = Color.Accent,
                Padding = new Thickness(5),
                Content = new StackLayout
                {
                    Orientation = StackOrientation.Horizontal,
                    Spacing = 15,

                    Children =
                    {
                        new BoxView
                        {
                            Color = color
                        },
                        new Label
                        {
                            Text = name,
                            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                            FontAttributes = FontAttributes.Bold,
                            VerticalOptions = LayoutOptions.Center,
                            HorizontalOptions = LayoutOptions.StartAndExpand
                        },
                    }
                }
            };

        }
    }
}

Merk op hoe er een lijst met objecten wordt aangemaakt die de kleuren bevat.

var colors = new[]
{
new { value = Color.White, name = "White" },
new { value = Color.Silver, name = "Silver" },
new { value = Color.Gray, name = "Gray" },
new { value = Color.Black, name = "Black" },
new { value = Color.Red, name = "Red" },
new { value = Color.Maroon, name = "Maroon" },
new { value = Color.Yellow, name = "Yellow" },
new { value = Color.Olive, name = "Olive" },
new { value = Color.Lime, name = "Lime" },
new { value = Color.Green, name = "Green" },
new { value = Color.Aqua, name = "Aqua" },
new { value = Color.Teal, name = "Teal" },
new { value = Color.Blue, name = "Blue" },
new { value = Color.Navy, name = "Navy" },
new { value = Color.Pink, name = "Pink" },
new { value = Color.Fuchsia, name = "Fuchsia" },
new { value = Color.Purple, name = "Purple" }
};

Deze lijst worde doorlopen via:

foreach (var color in colors)
{
stackLayout.Children.Add(CreateColorView(color.value, color.name));
}

Het toevoegen aan de StackLayout gebeurt door een eigen functie die de waarde en de naam van de kleur als parameter meekrijgt.

CreateColorView(color.value, color.name)

Deze functie geeft een Frame terug, een Frame is van het type View.

View CreateColorView(Color color, string name)
{
return new Frame
{
...
}
};

Merk ook op dat de Padding device specifiek is (namelijk overal 5 behalve voor iOS waar de padding 20 is).

Padding = new Thickness(5, Device.OnPlatform(20, 5, 5), 5, 5);


Design guides

Onderstaande design guides sluiten aan bij wat besproken is in deze post. Ik raad aan deze zeker eens te bekijken.

Android

iOS

UWP


Behandelde Basiscompetenties uit de module ICT Programmeren – Specifieke ontwikkelomgeving: complexe functionaliteiten

  • IC BC246 – kan complexe ontwerpen in een specifieke ontwikkelomgeving maken
  • IC BC251 – kan een ontwerp in een specifieke ontwikkelomgeving verfijnen
  • IC BC253 – kan broncode in een specifieke ontwikkelomgeving optimaliseren
  • IC BC257 – heeft aandacht voor de gebruiksvriendelijkheid van de toepassing

Geef een reactie

  • Abonneer je op deze website d.m.v. e-mail

    Voer je e-mailadres in om je in te schrijven op deze website en e-mailmeldingen te ontvangen van nieuwe berichten.