Alexei Malashkevich
Alexei Malashkevich

Reputation: 1665

Xamarin.Forms Relative layout strange behavior

I face problem with relative layout. My target is to create similar layout:enter image description here

Disclaimer: This should be relative layout just because i need add some other elements which position depends on this two.

This is my code:

var layout = new RelativeLayout();

var box = new BoxView { BackgroundColor = Color.Olive, WidthRequest = 50, HeightRequest = 50 };

var label = new Label
{
    LineBreakMode = LineBreakMode.WordWrap,
    Text = "Here is a lot of text ..... Here is a lot of text";
};
layout.Children.Add(box, Constraint.Constant(10), Constraint.Constant(10));
layout.Children.Add(label,
    Constraint.RelativeToView(box, (relativeLayout, view) => view.X + view.Width + 20),
    Constraint.RelativeToView(box, (relativeLayout, view) => view.Y),
    //Constraint.RelativeToParent(relativeLayout => relativeLayout.Width - 20 - 50 -10));


MainPage = new ContentPage
{
    Content = layout    
};

Here is my problem. If I not add commented line then label is out of the screen. Like here:enter image description here

If I add commented string (which is width constraint) then there is another strange thing: Text is not fully displayed. I mean that there should be ~10 more words but they suddenly disappear. enter image description here

I don't set any Height constraints so it should not limit the size of label.

Could you please help me with this? Thank you!

Upvotes: 1

Views: 2655

Answers (2)

Daniel Luberda
Daniel Luberda

Reputation: 7454

  • Be sure you're setting RelativeLayout HorizontalOptions and VerticalOptions to fill the screen
  • Calculate label X Constraint correctly view.X + view.Width + 20 -> view.X + view.Width + 10
  • The label height is incorrect because you didn't set it. When you use AbsoluteLayout or RelativeLayout you MUST set its children sizes manually. It's how it's designed.

Here is working example:

    var layout = new RelativeLayout() {
        HorizontalOptions = LayoutOptions.FillAndExpand,
        VerticalOptions = LayoutOptions.FillAndExpand
    };

    const double boxSize = 50;
    const double margin = 10;

    var box = new BoxView { 
        BackgroundColor = Color.Olive, 
        WidthRequest = boxSize, 
        HeightRequest = boxSize 
    };

    var label = new Label {
        LineBreakMode = LineBreakMode.WordWrap,
        Text = "Cras efficitur, sem a scelerisque pretium, leo turpis cursus lacus, id consequat erat risus sit amet tortor. Nullam fringilla vestibulum mauris, vel fringilla lectus molestie eget. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent quis elit eu nulla varius consectetur. Ut eleifend odio at malesuada lacinia. Fusce neque orci, efficitur nec condimentum et, volutpat id odio. Quisque vel metus vitae lectus vulputate placerat. Aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec suscipit, ipsum nec tincidunt porta, enim lacus consequat magna, nec scelerisque lacus lacus luctus mi. Proin rutrum luctus libero, sed lacinia tellus. Nunc dapibus arcu dui, quis bibendum elit interdum sit amet. Vivamus sed consequat mi. Aliquam sagittis ante ac massa bibendum, eu pharetra diam malesuada. Duis maximus magna id lorem lacinia, sed consectetur quam sagittis. Fusce at pulvinar ex."
    };
    layout.Children.Add(box, Constraint.Constant(margin), Constraint.Constant(margin));

    layout.Children.Add(label,
        Constraint.RelativeToView(box, (relativeLayout, view) => view.X + boxSize + margin),
        Constraint.RelativeToView(box, (relativeLayout, view) => view.Y),
        Constraint.RelativeToParent((relativeLayout) => relativeLayout.Width - boxSize - margin * 3),
        Constraint.RelativeToParent((relativeLayout) => relativeLayout.Height * 0.8f)); // eg. 80% of its parent

Upvotes: 1

JordanMazurke
JordanMazurke

Reputation: 1123

There is nothing stopping you leveraging the layout of a stack within your relative layout.

E.g.

var stackLayout = new StackLayout {
    Orientation = StackOrientation.Horizontal,
    Padding = new Thickness (20, 10, 10, 0),
    Children = {
        new BoxView { 
            BackgroundColor = Color.Olive, 
            WidthRequest = 50, 
            HeightRequest = 50, 
            HorizontalOptions = LayoutOptions.Start,
            VerticalOptions = LayoutOptions.Start
        },
        new Label {
            LineBreakMode = LineBreakMode.WordWrap,
            HorizontalOptions = LayoutOptions.FillAndExpand,
            Text = "Here is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of textHere is a lot of text ..... Here is a lot of text"
        }
    }
};

var relLayout = new RelativeLayout ();
relLayout.Children.Add (stackLayout, 
    Constraint.Constant (0), 
    Constraint.Constant (0), 
    Constraint.RelativeToParent((p)=>{return p.Width;}),
    Constraint.RelativeToParent((p)=>{return p.Height;})
);

Of course, you will need to tinker around with the values but the basic premise is there.

Upvotes: 0

Related Questions