two stacklayout sobre puede otro introducir horizontal fillandexpand example xamarin.forms

xamarin.forms - stacklayout - ¿Cómo se usa RelativeLayout con controles que dependen de su propio tamaño para su posición?



xamarin stacklayout horizontal xaml (1)

Profundizando en la implementación (actual) de RelativeLayout , encontré una verdad que no esperaba: no consulta el método GetSizeRequest() una vista ni llama a su método Layout() antes de que se calculen las restricciones, porque esas restricciones pueden afectar el control tamaño final La consecuencia: mientras se calculan las restricciones, los límites del control reflejan su posición y tamaño antiguos.

Para "arreglarlo", llame a GetSizeRequest () de la vista dentro de las restricciones que necesitan el tamaño más actualizado del control:

public class MainPage : ContentPage { public MainPage() { var layout = new RelativeLayout(); var label = new Label() { Text = "I want to be right-aligned." }; Func<RelativeLayout, double> getLabelWidth = (parent) => label.GetSizeRequest(layout.Width, layout.Height).Request.Width; layout.Children.Add(label, Constraint.RelativeToParent((rl) => rl.Width - getLabelWidth(rl)), Constraint.Constant(10)); var button = new Button() { Text = "Invalidate" }; button.Clicked += (object sender, EventArgs e) => layout.ForceLayout(); layout.Children.Add(button, Constraint.Constant(10), Constraint.Constant(10)); Content = layout; } }

Tengo bastantes otros problemas con el diseño que requieren muchas llamadas InvalidateLayout () adicionales, así que empiezo a preguntar si entiendo cómo funciona RelativeLayout.

Aquí hay un ejemplo muy simple de una interfaz de usuario que quiere una etiqueta alineada a la derecha:

public class MainPage : ContentPage { public MainPage() { var layout = new RelativeLayout(); var label = new Label() { Text = "I want to be right-aligned." }; layout.Children.Add(label, Constraint.RelativeToParent((rl) => rl.Width - label.Width), Constraint.Constant(10)); var button = new Button() { Text = "Invalidate" }; button.Clicked += (object sender, EventArgs e) => layout.ForceLayout(); layout.Children.Add(button, Constraint.Constant(10), Constraint.Constant(10)); Content = layout; } }

Espero que esto comience con la etiqueta alineada correctamente, pero no alinea la etiqueta correctamente hasta que se forme otra pasada de diseño. Al anular métodos como OnSizeRequest () en mi control personalizado, he determinado que esto se debe a que las llamadas a OnSizeRequest () no ocurren hasta después de las llamadas a la restricción de RelativeLayout lambdas. Entonces, cuando la página está distribuida, el ancho de la etiqueta es -1. Cuando se llama a ForceLayout () más tarde, la etiqueta ha tenido la oportunidad de realizar su lógica de diseño y ha establecido correctamente la propiedad Ancho, por lo que se distribuye correctamente.

En un contexto más amplio, estoy tratando de crear un botón que, al hacer clic, se desvanezca y una etiqueta se deslice en el lugar donde estaba. Debe estar alineado en la esquina inferior derecha de mi diseño, pero descubro que la modificación de Opacity o IsVisible solo actualiza el diseño de forma incoherente. El único comportamiento constante es RelativeLayout realmente le gusta pedir el tamaño del control antes de que tenga la oportunidad de cambiar el tamaño.

¿Estoy interpretando cómo usar un error RelativeLayout, o es un error en su lógica?