Xamarin.Forms RelativeLayout

Download Sample Scaricare l'esempio

Xamarin.Forms RelativeLayout

Un RelativeLayout oggetto viene utilizzato per posizionare e ridimensionare elementi figlio rispetto alle proprietà degli elementi di layout o di pari livello. In questo modo è possibile creare interfacce utente che vengono ridimensionate proporzionalmente tra le dimensioni del dispositivo. Inoltre, a differenza di altre classi di layout, RelativeLayout è in grado di posizionare gli elementi figlio in modo che si sovrappongano.

La RelativeLayout classe definisce le proprietà seguenti:

  • XConstraint, di tipo Constraint, che è una proprietà associata che rappresenta il vincolo sulla posizione X dell'elemento figlio.
  • YConstraint, di tipo Constraint, che è una proprietà associata che rappresenta il vincolo sulla posizione Y dell'elemento figlio.
  • WidthConstraint, di tipo Constraint, che è una proprietà associata che rappresenta il vincolo sulla larghezza dell'elemento figlio.
  • HeightConstraint, di tipo Constraint, che è una proprietà associata che rappresenta il vincolo sull'altezza dell'elemento figlio.
  • BoundsConstraint, di tipo BoundsConstraint, che è una proprietà associata che rappresenta il vincolo sulla posizione e sulle dimensioni dell'elemento figlio. Questa proprietà non può essere facilmente utilizzata da XAML.

Queste proprietà sono supportate da BindableProperty oggetti, il che significa che le proprietà possono essere destinazioni di data binding e stili. Per altre informazioni sulle proprietà associate, vedere Xamarin.Forms Proprietà associate.

Nota

La larghezza e l'altezza di un elemento figlio in un RelativeLayout oggetto possono essere specificate anche tramite le proprietà e HeightRequest dell'elemento WidthRequest figlio, anziché le WidthConstraint proprietà associate e HeightConstraint .

La RelativeLayout classe deriva dalla Layout<T> classe , che definisce una Children proprietà di tipo IList<T>. La Children proprietà è la ContentProperty della Layout<T> classe e pertanto non deve essere impostata in modo esplicito da XAML.

Suggerimento

Evitare di usare un elemento RelativeLayout quando possibile. Causa un notevole aumento del lavoro per la CPU.

Vincoli

All'interno di , RelativeLayoutla posizione e le dimensioni degli elementi figlio vengono specificate come vincoli usando valori assoluti o valori relativi. Quando non vengono specificati vincoli, un elemento figlio verrà posizionato nell'angolo superiore sinistro del layout.

La tabella seguente illustra come specificare i vincoli in XAML e C#:

XAML C#
Valori assoluti I vincoli assoluti vengono specificati impostando le RelativeLayout proprietà associate sui double valori. I vincoli assoluti vengono specificati dal Constraint.Constant metodo o tramite l'overload Children.Add che richiede un Func<Rectangle> argomento .
Valori relativi I vincoli relativi vengono specificati impostando le RelativeLayout proprietà associate su Constraint oggetti restituiti dall'estensione di ConstraintExpression markup. I vincoli relativi vengono specificati dagli Constraint oggetti restituiti dai metodi della Constraint classe .

Per altre informazioni sulla specifica dei vincoli tramite valori assoluti, vedere Posizionamento assoluto e ridimensionamento. Per altre informazioni sulla specifica dei vincoli tramite valori relativi, vedere Posizionamento e ridimensionamento relativi.

In C#, gli elementi figlio possono essere aggiunti a RelativeLayout da tre Add overload. Per il primo overload è necessario Expression<Func<Rectangle>> specificare la posizione e le dimensioni di un elemento figlio. Il secondo overload richiede oggetti facoltativi per gli xargomenti , widthy, e height .Expression<Func<double>> Il terzo overload richiede oggetti facoltativi per gli xargomenti , widthy, e height .Constraint

È possibile modificare la posizione e le dimensioni di un elemento figlio in un RelativeLayout con i SetXConstraintmetodi , SetYConstraintSetWidthConstraint, e SetHeightConstraint . Il primo argomento di ognuno di questi metodi è figlio e il secondo è un Constraint oggetto . Inoltre, il SetBoundsConstraint metodo può essere usato anche per modificare la posizione e le dimensioni di un elemento figlio. Il primo argomento di questo metodo è figlio e il secondo è un BoundsConstraint oggetto .

Posizionamento assoluto e ridimensionamento

Un RelativeLayout oggetto può posizionare e ridimensionare gli elementi figlio usando valori assoluti, specificati in unità indipendenti dal dispositivo, che definiscono in modo esplicito dove devono essere posizionati gli elementi figlio nel layout. Questa operazione viene ottenuta aggiungendo elementi figlio alla Children raccolta di un RelativeLayout oggetto e impostando le XConstraintproprietà associate , YConstraint, WidthConstrainte HeightConstraint su ogni elemento figlio in valori di posizione e/o dimensioni assoluti.

Avviso

L'uso di valori assoluti per posizionare e ridimensionare gli elementi figlio può essere problematico, perché i diversi dispositivi hanno dimensioni e risoluzioni dello schermo diverse. Di conseguenza, le coordinate per il centro dello schermo su un dispositivo possono essere offset su altri dispositivi.

Il codice XAML seguente mostra un RelativeLayout oggetto i cui elementi figlio sono posizionati usando valori assoluti:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RelativeLayoutDemos.Views.StylishHeaderDemoPage"
             Title="Stylish header demo">
    <RelativeLayout Margin="20">
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="0"
                 RelativeLayout.YConstraint="10"
                 RelativeLayout.WidthConstraint="200"
                 RelativeLayout.HeightConstraint="5" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="0"
                 RelativeLayout.YConstraint="20"
                 RelativeLayout.WidthConstraint="200"
                 RelativeLayout.HeightConstraint="5" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="10"
                 RelativeLayout.YConstraint="0"
                 RelativeLayout.WidthConstraint="5"
                 RelativeLayout.HeightConstraint="65" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="20"
                 RelativeLayout.YConstraint="0"
                 RelativeLayout.WidthConstraint="5"
                 RelativeLayout.HeightConstraint="65" />
        <Label Text="Stylish header"
               FontSize="24"
               RelativeLayout.XConstraint="30"
               RelativeLayout.YConstraint="25" />
    </RelativeLayout>
</ContentPage>

In questo esempio la posizione di ogni BoxView oggetto viene definita usando i valori specificati nelle XConstraint proprietà associate e YConstraint . Le dimensioni di ogni BoxView oggetto vengono definite usando i valori specificati nelle WidthConstraint proprietà associate e HeightConstraint . La posizione dell'oggetto Label viene definita anche utilizzando i valori specificati nelle XConstraint proprietà associate e YConstraint . Tuttavia, i valori delle dimensioni non vengono specificati per e Labelquindi non sono vincolati e le dimensioni stesse. In tutti i casi, i valori assoluti rappresentano unità indipendenti dal dispositivo.

Gli screenshot seguenti visualizzano il layout finale:

Children placed in a RelativeLayout using absolute values

Il codice C# equivalente è illustrato di seguito:

public class StylishHeaderDemoPageCS : ContentPage
{
    public StylishHeaderDemoPageCS()
    {
        RelativeLayout relativeLayout = new RelativeLayout
        {
            Margin = new Thickness(20)
        };

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(0, 10, 200, 5));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(0, 20, 200, 5));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(10, 0, 5, 65));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(20, 0, 5, 65));

        relativeLayout.Children.Add(new Label
        {
            Text = "Stylish Header",
            FontSize = 24
        }, Constraint.Constant(30), Constraint.Constant(25));

        Title = "Stylish header demo";
        Content = relativeLayout;
    }
}

In questo esempio, BoxView gli oggetti vengono aggiunti all'oggetto RelativeLayout utilizzando un Add overload che richiede un Expression<Func<Rectangle>> oggetto per specificare la posizione e le dimensioni di ogni elemento figlio. La posizione di Label è definita usando un Add overload che richiede oggetti facoltativi Constraint , in questo caso creati dal Constraint.Constant metodo .

Nota

Un RelativeLayout oggetto che usa valori assoluti può posizionare e ridimensionare gli elementi figlio in modo che non si adattino ai limiti del layout.

Posizionamento e ridimensionamento relativi

Un RelativeLayout oggetto può posizionare e ridimensionare elementi figlio utilizzando valori relativi alle proprietà del layout o elementi di pari livello. Questa operazione viene ottenuta aggiungendo elementi figlio alla Children raccolta di RelativeLayout e impostando le XConstraintproprietà associate , YConstraint, WidthConstrainte HeightConstraint in ogni elemento figlio su valori relativi tramite Constraint oggetti .

I vincoli possono essere una costante, rispetto a un elemento padre o rispetto a un elemento di pari livello. Il tipo di vincolo è rappresentato dall'enumerazione ConstraintType , che definisce i membri seguenti:

  • RelativeToParent, che indica un vincolo relativo a un elemento padre.
  • RelativeToView, che indica un vincolo relativo a una vista (o di pari livello).
  • Constant, che indica un vincolo costante.

Estensione di markup dei vincoli

In XAML, un Constraint oggetto può essere creato dall'estensione di ConstraintExpression markup. Questa estensione di markup viene in genere usata per correlare la posizione e le dimensioni di un elemento figlio all'interno di un RelativeLayout elemento padre o a un elemento di pari livello.

La ConstraintExpression classe definisce le proprietà seguenti:

  • Constant, di tipo double, che rappresenta il valore costante del vincolo.
  • ElementName, di tipo string, che rappresenta il nome di un elemento di origine in base al quale calcolare il vincolo.
  • Factor, di tipo double, che rappresenta il fattore in base al quale ridimensionare una dimensione vincolata, rispetto all'elemento di origine. Per impostazione predefinita, questa proprietà è 1.
  • Property, di tipo string, che rappresenta il nome della proprietà sull'elemento di origine da utilizzare nel calcolo del vincolo.
  • Type, di tipo ConstraintType, che rappresenta il tipo del vincolo.

Per altre informazioni sulle Xamarin.Forms estensioni di markup, vedi Estensioni di markup XAML.

Il codice XAML seguente mostra un RelativeLayout oggetto i cui elementi figlio sono vincolati dall'estensione di ConstraintExpression markup:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RelativeLayoutDemos.Views.RelativePositioningAndSizingDemoPage"
             Title="RelativeLayout demo">
    <RelativeLayout>
        <BoxView Color="Red"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}" />
        <BoxView Color="Green"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Constant=-40}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}" />
        <BoxView Color="Blue"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Constant=-40}" />
        <BoxView Color="Yellow"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Constant=-40}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Constant=-40}" />

        <!-- Centered and 1/3 width and height of parent -->
        <BoxView x:Name="oneThird"
                 Color="Silver"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.33}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.33}"
                 RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.33}"
                 RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.33}" />

        <!-- 1/3 width and height of previous -->
        <BoxView Color="Black"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=X}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Y}"
                 RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Width, Factor=0.33}"
                 RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Height, Factor=0.33}" />
    </RelativeLayout>
</ContentPage>

In questo esempio la posizione di ogni BoxView oggetto viene definita impostando le XConstraint proprietà associate e YConstraint . La prima BoxView ha XConstraint le proprietà associate e YConstraint impostate su costanti, che sono valori assoluti. Tutti gli oggetti rimanenti BoxView hanno la loro posizione impostata utilizzando almeno un valore relativo. Ad esempio, l'oggetto giallo BoxView imposta la XConstraint proprietà associata sulla larghezza del relativo elemento padre (il RelativeLayout) meno 40. Analogamente, imposta BoxView la YConstraint proprietà associata sull'altezza del padre meno 40. In questo modo si garantisce che il giallo BoxView venga visualizzato nell'angolo inferiore destro dello schermo.

Nota

BoxView gli oggetti che non specificano una dimensione vengono ridimensionati automaticamente a 40x40 per Xamarin.Forms.

L'argento BoxView denominato oneThird è posizionato centralmente rispetto al relativo elemento padre. Viene anche ridimensionata rispetto al padre, essendo un terzo della larghezza e dell'altezza. Questa operazione viene ottenuta impostando le XConstraint proprietà associate e WidthConstraint sulla larghezza dell'elemento padre (il RelativeLayout), moltiplicato per 0,33. Analogamente, le YConstraint proprietà associate e HeightConstraint vengono impostate sull'altezza dell'elemento padre, moltiplicato per 0,33.

Il nero BoxView è posizionato e ridimensionato rispetto all'oggetto oneThirdBoxView. Questa operazione viene ottenuta impostando XConstraint rispettivamente le proprietà associate e YConstraint sui X valori e Y dell'elemento di pari livello. Analogamente, le dimensioni sono impostate su un terzo della larghezza e dell'altezza dell'elemento di pari livello. Questa operazione viene ottenuta impostando WidthConstraint rispettivamente le proprietà associate e HeightConstraint sui Width valori e Height dell'elemento di pari livello, che vengono quindi moltiplicati per 0,33.

Lo screenshot seguente mostra il layout risultante:

Children placed in a RelativeLayout using relative values

Oggetti vincolo

La Constraint classe definisce i metodi statici pubblici seguenti, che restituiscono Constraint oggetti:

  • Constant, che vincola un elemento figlio a una dimensione specificata con un oggetto double.
  • FromExpression, che vincola un elemento figlio usando un'espressione lambda.
  • RelativeToParent, che vincola un figlio rispetto alle dimensioni del padre.
  • RelativeToView, che vincola un elemento figlio rispetto alle dimensioni di una vista.

Inoltre, la BoundsConstraint classe definisce un singolo metodo, FromExpression, che restituisce un BoundsConstraint oggetto che vincola la posizione e le dimensioni di un figlio con un oggetto Expression<Func<Rectangle>>. Questo metodo può essere utilizzato per impostare la BoundsConstraint proprietà associata.

Il codice C# seguente mostra un oggetto RelativeLayout i cui elementi figlio sono vincolati dagli Constraint oggetti :

public class RelativePositioningAndSizingDemoPageCS : ContentPage
{
    public RelativePositioningAndSizingDemoPageCS()
    {
        RelativeLayout relativeLayout = new RelativeLayout();

        // Four BoxView's
        relativeLayout.Children.Add(
            new BoxView { Color = Color.Red },
            Constraint.Constant(0),
            Constraint.Constant(0));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Green },
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width - 40;
            }), Constraint.Constant(0));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Blue },
            Constraint.Constant(0),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height - 40;
            }));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Yellow },
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width - 40;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height - 40;
            }));

        // Centered and 1/3 width and height of parent
        BoxView silverBoxView = new BoxView { Color = Color.Silver };
        relativeLayout.Children.Add(
            silverBoxView,
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height * 0.33;
            }));

        // 1/3 width and height of previous
        relativeLayout.Children.Add(
            new BoxView { Color = Color.Black },
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.X;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Y;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Width * 0.33;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Height * 0.33;
            }));

        Title = "RelativeLayout demo";
        Content = relativeLayout;
    }
}

In questo esempio, gli elementi figlio vengono aggiunti all'oggetto usando l'overload che richiede un oggetto facoltativo Constraint per gli xargomenti , ywidth, e height .RelativeLayoutAdd

Nota

Un RelativeLayout oggetto che usa valori relativi può posizionare e ridimensionare gli elementi figlio in modo che non si adattino ai limiti del layout.