Xamarin.Forms RelativeLayout
Un RelativeLayout
sirve para colocar y ajustar el tamaño de los elementos secundarios en relación con las propiedades del diseño o los elementos del mismo nivel. Esto permite crear interfaces de usuario que se escalan proporcionalmente entre tamaños de dispositivo. Además, a diferencia de otras clases de diseño, RelativeLayout
es capaz de colocar elementos secundarios para que se superpongan.
La clase RelativeLayout
define las propiedades siguientes:
XConstraint
, de tipoConstraint
, que es una propiedad adjunta que representa la restricción en la posición X del elemento secundario.YConstraint
, de tipoConstraint
, que es una propiedad adjunta que representa la restricción en la posición Y del elemento secundario.WidthConstraint
, de tipoConstraint
, que es una propiedad adjunta que representa la restricción en el ancho del elemento secundario.HeightConstraint
, de tipoConstraint
, que es una propiedad adjunta que representa la restricción en el alto del elemento secundario.BoundsConstraint
, de tipoBoundsConstraint
, que es una propiedad adjunta que representa la restricción en la posición y el tamaño del elemento secundario. Esta propiedad no se puede consumir fácilmente desde XAML.
Todas estas propiedades están respaldadas por objetos BindableProperty
, lo que significa que las propiedades pueden ser destinos de los enlaces de datos, y se les puede aplicar estilos. Para obtener más información sobre las propiedades adjuntas, consulte Xamarin.FormsPropiedades asociadas.
Nota:
También se puede especificar el ancho y el alto de un elemento secundario en un RelativeLayout
a través de las propiedades WidthRequest
y HeightRequest
del elemento secundario, en lugar de hacerlo en las propiedades adjuntas WidthConstraint
y HeightConstraint
.
La clase RelativeLayout
deriva de la clase Layout<T>
, que define una propiedad Children
de tipo IList<T>
. La propiedad Children
es ContentProperty
de la clase Layout<T>
y, por tanto, no es necesario establecerla explícitamente desde XAML.
Sugerencia
Evite el uso de un RelativeLayout
siempre que sea posible. Como resultado, la CPU tendrá que realizar mucho más trabajo.
Restricciones
Dentro de un RelativeLayout
, la posición y el tamaño de los elementos secundarios se especifican como restricciones mediante valores absolutos o relativos. Cuando no se especifican restricciones, un elemento secundario se colocará en la esquina superior izquierda del diseño.
En la tabla siguiente se muestra cómo especificar restricciones en XAML y C#:
XAML | C# | |
---|---|---|
Valores absolutos | Las restricciones absolutas se especifican estableciendo las propiedades adjuntas RelativeLayout en valores double . |
Las restricciones absolutas se especifican mediante el método Constraint.Constant o mediante la sobrecarga Children.Add que requiere un argumento Func<Rectangle> . |
Valores relativos | Las restricciones relativas se especifican estableciendo las propiedades adjuntas RelativeLayout en objetos Constraint devueltos por la extensión de marcado ConstraintExpression . |
Las restricciones relativas se especifican mediante objetos Constraint devueltos por métodos de la clase Constraint . |
Para obtener más información sobre cómo especificar restricciones mediante valores absolutos, consulte Posicionamiento y ajuste de tamaño absolutos. Para obtener más información sobre cómo especificar restricciones mediante valores relativos, consulte Posicionamiento y ajuste de tamaño relativos.
En C#, los elementos secundarios se pueden agregar a RelativeLayout
mediante tres sobrecargas Add
. La primera sobrecarga requiere que un Expression<Func<Rectangle>>
especifique la posición y el tamaño de un elemento secundario. La segunda sobrecarga requiere objetos Expression<Func<double>>
opcionales para los argumentos x
, y
, width
y height
. La tercera sobrecarga requiere objetos Constraint
opcionales para los argumentos x
, y
, width
y height
.
Es posible cambiar la posición y el tamaño de un elemento secundario de un RelativeLayout
con los métodos SetXConstraint
, SetYConstraint
, SetWidthConstraint
y SetHeightConstraint
. El primer argumento para cada uno de estos métodos es el elemento secundario y el segundo, un objeto Constraint
. Además, el método SetBoundsConstraint
también se puede usar para cambiar la posición y el tamaño de un elemento secundario. El primer argumento para este método es el elemento secundario; el segundo es un objeto BoundsConstraint
.
Posición absoluta y ajuste de tamaño
Un RelativeLayout
puede colocar y ajustar el tamaño de los elementos secundarios mediante valores absolutos, especificados en unidades independientes del dispositivo, que definen explícitamente dónde deben colocarse los elementos secundarios en el diseño. Esto se logra agregando elementos secundarios a la colección Children
de un RelativeLayout
, y estableciendo las propiedades adjuntas XConstraint
, YConstraint
, WidthConstraint
y HeightConstraint
en cada elemento secundario a valores absolutos de posición o tamaño.
Advertencia
El uso de valores absolutos para colocar y ajustar el tamaño de los elementos secundarios puede ser problemático, ya que los diferentes dispositivos tienen diferentes tamaños de pantalla y resoluciones. Por lo tanto, las coordenadas del centro de la pantalla en un dispositivo pueden desplazarse en otros dispositivos.
En el código XAML siguiente se muestra un RelativeLayout
cuyos elementos secundarios se colocan con valores absolutos:
<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>
En este ejemplo, la posición de cada objeto BoxView
se define mediante los valores especificados en las propiedades adjuntas XConstraint
y YConstraint
. El tamaño de cada BoxView
se define mediante los valores especificados en las propiedades adjuntas WidthConstraint
y HeightConstraint
. La posición del objeto Label
también se define mediante los valores especificados en las propiedades adjuntas XConstraint
y YConstraint
. Sin embargo, los valores de tamaño no se especifican para Label
y, por tanto, no tiene restricciones y se dimensiona por sí misma. En todos los casos, los valores absolutos representan unidades independientes del dispositivo.
En las capturas de pantalla siguientes se muestra el diseño resultante:
El código de C# equivalente se muestra a continuación:
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;
}
}
En este ejemplo, se agregan objetos BoxView
a RelativeLayout
mediante una sobrecarga Add
que requiere que un Expression<Func<Rectangle>>
especifique la posición y el tamaño de cada elemento secundario. La posición de Label
se define mediante una sobrecarga Add
que requiere objetos Constraint
opcionales, en este caso creados por el método Constraint.Constant
.
Nota:
Un RelativeLayout
que usa valores absolutos puede colocar y ajustar los elementos secundarios para que no se ajusten a los límites del diseño.
Posicionamiento y ajuste de tamaño relativos
Un RelativeLayout
puede colocar y ajustar el tamaño de los elementos secundarios mediante valores relativos a las propiedades del diseño o elementos del mismo nivel. Esto se logra agregando elementos secundarios a la colección Children
del RelativeLayout
, y estableciendo las propiedades adjuntas XConstraint
, YConstraint
, WidthConstraint
y HeightConstraint
en cada elemento secundario a valores relativos mediante objetos Constraint
.
Las restricciones pueden ser una constante, relativa a un elemento primario o a un elemento del mismo nivel. El tipo de restricción se representa mediante la enumeración ConstraintType
, que define los siguientes miembros:
RelativeToParent
, que indica una restricción relativa a un elemento primario.RelativeToView
, que indica una restricción relativa a una vista (o del mismo nivel).Constant
, que indica una restricción constante.
Extensión de marcado de restricciones
En XAML, la extensión de marcado ConstraintExpression
puede crear un objeto Constraint
. Esta extensión de marcado se usa normalmente para relacionar la posición y el tamaño de un elemento secundario dentro de un RelativeLayout
a su elemento primario o a un elemento del mismo nivel.
La clase ConstraintExpression
define las propiedades siguientes:
Constant
, de tipodouble
, que representa el valor constante de restricción.ElementName
, de tipostring
, que representa el nombre de un elemento de origen con el que debe calcularse la restricción.Factor
, de tipodouble
, que representa el factor por el que se escala una dimensión restringida, en relación con el elemento de origen. Esta propiedad tiene como valor predeterminado 1.Property
, de tipostring
, que representa el nombre de la propiedad en el elemento de origen que se va a usar en el cálculo de restricciones.Type
, de tipoConstraintType
, que representa el tipo de la restricción.
Para más información sobre las extensiones de marcado de Xamarin.Forms, vea Extensiones de marcado para el lenguaje XAML.
En el código XAML siguiente se muestra un RelativeLayout
cuyos elementos secundarios están restringidos por la extensión de marcado ConstraintExpression
:
<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>
En este ejemplo, la posición de cada objeto BoxView
se define estableciendo las propiedades adjuntas XConstraint
y YConstraint
. La primera BoxView
tiene sus propiedades adjuntas XConstraint
y YConstraint
establecidas en constantes, que son valores absolutos. Todos los objetos BoxView
restantes tienen su posición establecida mediante al menos un valor relativo. Por ejemplo, el objeto BoxView
amarillo establece la propiedad adjunta XConstraint
en el ancho de su elemento primario (RelativeLayout
) menos 40. Del mismo modo, BoxView
establece la propiedad adjunta YConstraint
en el alto de su elemento primario menos 40. Así se garantiza que el objeto BoxView
amarillo aparezca en la esquina inferior derecha de la pantalla.
Nota:
Los objetos BoxView
que no especifican ningún tamaño se ajustan automáticamente a 40x40 por Xamarin.Forms.
El objeto BoxView
plateado denominado oneThird
se coloca centralmente, en relación con su elemento primario. También tiene un tamaño relativo a su elemento primario, siendo un tercio de su ancho y alto. Esto se logra estableciendo las propiedades adjuntas XConstraint
y WidthConstraint
en el ancho del elemento primario (RelativeLayout
), multiplicado por 0,33. De forma similar, las propiedades adjuntas YConstraint
y HeightConstraint
se establecen en el alto del elemento primario, multiplicado por 0,33.
El negro BoxView
se coloca y se ajusta al tamaño con respecto a oneThird
BoxView
. Esto se logra estableciendo sus propiedades adjuntas XConstraint
y YConstraint
en los valores X
y Y
, respectivamente, del elemento del mismo nivel. Del mismo modo, su tamaño se establece en un tercio del ancho y alto de su elemento del mismo nivel. Esto se logra estableciendo sus propiedades adjuntas WidthConstraint
y HeightConstraint
en los valores Width
y Height
del elemento del mismo nivel, respectivamente, que se multiplican por 0,33.
En la captura de pantalla siguiente se muestra el diseño resultante:
Objetos de restricción
La clase Constraint
define los siguientes métodos estáticos públicos, que devuelven objetos Constraint
:
Constant
, que restringe un elemento secundario a un tamaño especificado condouble
.FromExpression
, que restringe un elemento secundario mediante una expresión lambda.RelativeToParent
, que restringe un elemento secundario con respecto al tamaño de su elemento primario.RelativeToView
, que restringe un elemento secundario con respecto al tamaño de una vista.
Además, la clase BoundsConstraint
define un único método, FromExpression
, que devuelve un BoundsConstraint
que restringe la posición y el tamaño de un elemento secundario con Expression<Func<Rectangle>>
. Este método se puede usar para establecer la propiedad adjunta BoundsConstraint
.
El siguiente código de C# muestra un RelativeLayout
cuyos elementos secundarios están restringidos por objetos Constraint
:
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;
}
}
En este ejemplo, se agregan elementos secundarios a RelativeLayout
mediante la sobrecarga Add
que requiere un objeto Constraint
opcional para los argumentos x
, y
, width
y height
.
Nota:
Un RelativeLayout
que usa valores relativos puede colocar y ajustar los elementos secundarios para que no se ajusten a los límites del diseño.