Mobiele apps programmeren met Xamarin – Layout – Grid

print

Inhoud


Wat vooraf ging


Grid

We hebben reeds gezien dat u een StackLayout gebruik als u de elementen wilt stapelen, verticaal of horizontaal.

Wanneer u echter uw pagina wilt opdelen in een aantal rijen en kolommen, dan kunt u beter opteren voor een Grid.

Een Grid wordt gebruikt om de pagina, of een deel van de pagina, op te delen in rijen en kolommen. Iedere cel, de kruising van een kolom en een rij, kan op zijn beurt content bevatten. Deze content kan een gewone View zijn maar eventueel ook een andere Layout.

Rijen en kolommen

Een Grid bevat rijen (RowDefinitions) en kolommen (ColumnDefinitions). Onderstaande code maakt een Grid bestaande uit 3 rijen en 2 kolommen uniform verdeeld.

Moest u deze code uittesten dan zal u niets te zien krijgen. Een Grid heeft immers geen randen.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
</Grid>

Hoogte van de rijen en breedte van de kolommen instellen

De hoogte en de breedte van een rij en kolommen kunnen

  • automatisch aangepast worden aan de inhoud – de waarde auto
  • een vaste waarde hebben – een integer waarde
  • een proportionele inname van de vrije ruimte beslaan – aangeduid door een * of een integer waarde gevolgd door een *. Bv. Height="2*" zal tweemaal zo hoog zijn dan Height="*".

Onderstaande Grid heeft:

  • Drie rijen en twee kolommen.
  • De onderste rij is exact 200px hoog.
  • De bovenste rij moet tweemaal zo hoog zijn als de middelste rij.
  • De meest linkse kolom moet automatisch aangepast worden aan de inhoud van de kolom.
  • De meest rechts kolom moet de overige beschikbare ruimte innemen.

XAML

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="200" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
</Grid>

C#

var grid = new Grid();

grid.RowDefinitions.Add (new RowDefinition 
{ 
	Height = new GridLength(2, GridUnitType.Star) 
});

grid.RowDefinitions.Add (new RowDefinition 
{ 
	Height = new GridLength(1, GridUnitType.Star) 
});

grid.RowDefinitions.Add (new RowDefinition 
{ 
	Height = new GridLength(200)
});

grid.ColumnDefinitions.Add (new ColumnDefinition
{ 
	Width = new GridLength(1, GridUnitType.Auto)  
});

grid.ColumnDefinitions.Add (new ColumnDefinition
{ 
	Width = new GridLength(1, GridUnitType.Star)  
});

Ik zou durven stellen dat de XAML iets eenvoudiger is.

Elementen toevoegen aan de grid

Nu we de Grid gedefinieerd hebben kunnen we de elementen toevoegen aan de Grid.

Dit gebeurt via attached properties die worden toegevoegd aan het element en verwijzen naar een kolom Grid.Column of rij Grid.Row van de Grid waarbinnen het element zich bevindt.

Onderstaande code maakt een Grid aan bestaande uit 2 rijen en 2 kolommen. Vervolgens worden Labels in elk van de cellen geplaatst.

XAML

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Label Text="Top Left" Grid.Row="0" Grid.Column="0" BackgroundColor="Blue"/>
    <Label Text="Top Right" Grid.Row="0" Grid.Column="1" BackgroundColor="Yellow"/>
    <Label Text="Bottom Left" Grid.Row="1" Grid.Column="0" BackgroundColor="Red"/>
    <Label Text="Bottom Right" Grid.Row="1" Grid.Column="1" BackgroundColor="Green"/>
</Grid>

C#

var grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

var topLeft = new Label { Text = "Top Left", BackgroundColor=Color.Blue };
var topRight = new Label { Text = "Top Right", BackgroundColor = Color.Yellow };
var bottomLeft = new Label { Text = "Bottom Left", BackgroundColor = Color.Red };
var bottomRight = new Label { Text = "Bottom Right", BackgroundColor = Color.Green };

grid.Children.Add(topLeft, 0, 0);
grid.Children.Add(topRight, 0, 1);
grid.Children.Add(bottomLeft, 1, 0);
grid.Children.Add(bottomRight, 1, 1);

Rijen en kolommen overspannen

Wanneer een element meerdere cellen in beslag neemt kan het de attached properties Grid.ColumnSpan voor het overspannen van kolommen of Grid.RowSpan voor het overspannen van rijen gebruiken. Onderstaand eenvoudig voorbeeld illustreert dit.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Label Text="Span 2 kolommen" Grid.Row="1" Grid.ColumnSpan="2" BackgroundColor="Yellow"/>
    <Label Text="Span 4 rijen" Grid.Row="0" Grid.Column="2" Grid.RowSpan="4" BackgroundColor="Red"/>
</Grid>

Complexer voorbeeld

  • Start een nieuw Xamarin-project en geef het een passende naam of voeg een pagina toe aan het vorige Layout-project.

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.Page4">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" />
    </ContentPage.Padding>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>

        <Label Text="Grid" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" FontSize="Large" HorizontalOptions="Center" />
        <Label Text="Autosized cell" Grid.Row="1" Grid.Column="0" TextColor="White" BackgroundColor="Blue" />
        <BoxView Color="Silver" HeightRequest="0" Grid.Row="1" Grid.Column="1" />
        <BoxView Color="Teal" Grid.Row="2" Grid.Column="0" />
        <Label Text="Leftover space" Grid.Row="2" Grid.Column="1" TextColor="Purple" BackgroundColor="Aqua" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
        <Label Text="Span two rows (or more if you want)" Grid.Row="1" Grid.Column="2" Grid.RowSpan="2" TextColor="Yellow" BackgroundColor="Blue" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
        <Label Text="Span two columns" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" TextColor="Blue" BackgroundColor="Yellow" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
        <Label Text="Fixed 100x100" Grid.Row="3" Grid.Column="2" TextColor="Aqua" BackgroundColor="Red" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />

    </Grid>

</ContentPage>

C#

using Xamarin.Forms;

namespace LayoutOpties
{
    public class GridC : ContentPage
    {
        public GridC()
        {
            Grid grid = new Grid
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                RowDefinitions =
                {
                    new RowDefinition { Height = GridLength.Auto },
                    new RowDefinition { Height = GridLength.Auto },
                    new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
                    new RowDefinition { Height = new GridLength(100, GridUnitType.Absolute) }
                },
                ColumnDefinitions =
                {
                    new ColumnDefinition { Width = GridLength.Auto },
                    new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                    new ColumnDefinition { Width = new GridLength(100, GridUnitType.Absolute) }
                }
            };

            grid.Children.Add(new Label
            {
                Text = "Grid",
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                HorizontalOptions = LayoutOptions.Center
            }, 0, 3, 0, 1);

            grid.Children.Add(new Label
            {
                Text = "Autosized cell",
                TextColor = Color.White,
                BackgroundColor = Color.Blue
            }, 0, 1);

            grid.Children.Add(new BoxView
            {
                Color = Color.Silver,
                HeightRequest = 0
            }, 1, 1);

            grid.Children.Add(new BoxView
            {
                Color = Color.Teal
            }, 0, 2);

            grid.Children.Add(new Label
            {
                Text = "Leftover space",
                TextColor = Color.Purple,
                BackgroundColor = Color.Aqua,
                HorizontalTextAlignment = TextAlignment.Center,
                VerticalTextAlignment = TextAlignment.Center,
            }, 1, 2);

            grid.Children.Add(new Label
            {
                Text = "Span two rows (or more if you want)",
                TextColor = Color.Yellow,
                BackgroundColor = Color.Navy,
                HorizontalTextAlignment = TextAlignment.Center,
                VerticalTextAlignment = TextAlignment.Center
            }, 2, 3, 1, 3);

            grid.Children.Add(new Label
            {
                Text = "Span 2 columns",
                TextColor = Color.Blue,
                BackgroundColor = Color.Yellow,
                HorizontalTextAlignment = TextAlignment.Center,
                VerticalTextAlignment = TextAlignment.Center
            }, 0, 2, 3, 4);

            grid.Children.Add(new Label
            {
                Text = "Fixed 100x100",
                TextColor = Color.Aqua,
                BackgroundColor = Color.Red,
                HorizontalTextAlignment = TextAlignment.Center,
                VerticalTextAlignment = TextAlignment.Center
            }, 2, 3);

            // Zorg voor een passende padding op iOS.
            this.Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 5);

            // Voeg de grid toe aan de pagina.
            this.Content = grid;
        }

    }
}

Opmerkingen

  • Standaard heeft Grid.ColumnSpan en Grid.RowSpan de waarde 0. Als u deze dus allebei zou weglaten dan komt het element in de eerste cel, linksboven, van de Grid te staan.
  • De eigenschappen ColumnSpacing en RowSpacing van de Grid kunnen gebruikt worden om ruimte tussen de rijen en kolommen te creëren.

In de video hieronder krijgt u een blik achter de schermen van attached properties.


Praktisch voorbeeld – Rekenmachine

Ik beperk me in dit voorbeeld tot de XAML-opmaak en enkel maar de opmaak, dit is dus geen volledig programma met werkende knoppen. De XAML-code zal in een verdere post ook nog opgekuist worden (volgens het DRY-principe (Don’t Repeat Yourself)) door het toepassen van stijlen.

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

    <Grid x:Name="controlGrid" RowSpacing="1" ColumnSpacing="1">
        <Grid.RowDefinitions>
            <RowDefinition Height="150" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Label Text="0" Grid.Row="0" Grid.ColumnSpan="4" HorizontalTextAlignment="End" VerticalTextAlignment="End" TextColor="White" FontSize="60" />
        <Button Text = "C" Grid.Row="1" Grid.Column="0" BackgroundColor="#ddd" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "+/-" Grid.Row="1" Grid.Column="1" BackgroundColor="#ddd" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "%" Grid.Row="1" Grid.Column="2" BackgroundColor="#ddd" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "div" Grid.Row="1" Grid.Column="3" BackgroundColor="#E8AD00" TextColor="White" BorderRadius="0" FontSize="40" />
        <Button Text = "7" Grid.Row="2" Grid.Column="0" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "8" Grid.Row="2" Grid.Column="1" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "9" Grid.Row="2" Grid.Column="2" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "X" Grid.Row="2" Grid.Column="3" BackgroundColor="#E8AD00" TextColor="White" BorderRadius="0" FontSize="40" />
        <Button Text = "4" Grid.Row="3" Grid.Column="0" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "5" Grid.Row="3" Grid.Column="1" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "6" Grid.Row="3" Grid.Column="2" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "-" Grid.Row="3" Grid.Column="3" BackgroundColor="#E8AD00" TextColor="White" BorderRadius="0" FontSize="40" />
        <Button Text = "1" Grid.Row="4" Grid.Column="0" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "2" Grid.Row="4" Grid.Column="1" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "3" Grid.Row="4" Grid.Column="2" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "+" Grid.Row="4" Grid.Column="3" BackgroundColor="#E8AD00" TextColor="White" BorderRadius="0" FontSize="40" />
        <Button Text = "0" Grid.ColumnSpan="2" Grid.Row="5" Grid.Column="0" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "." Grid.Row="5" Grid.Column="2" BackgroundColor="#eee" TextColor="Black" BorderRadius="0" FontSize="40" />
        <Button Text = "=" Grid.Row="5" Grid.Column="3" BackgroundColor="#E8AD00" TextColor="White" BorderRadius="0" FontSize="40" />
    </Grid>

</ContentPage>

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


Hoor het eens van iemand anders

Onderstaande video van Xamarin University bouwt een professionele layout op basis van een Grid. Ook hier wordt gebruik gemaakt van stijlen, iets dat wij pas later bespreken.


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.