Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] RelativeLayout doesn't lay out (position) child views correctly in horizontal direction when Flowdirection is Right To Left #11637

Open
hamiddd1980 opened this issue Aug 3, 2020 · 4 comments

Comments

@hamiddd1980
Copy link

Description

When Page FlowDirection is RightToLeft , RelativeLayout doesn't arrange (position) it's child views correctly in Horizontal axis(direction) in case Relative type of view is RelativeToView. (I mean the View is positioned relative to other view , not the parent)

Steps to Reproduce

  1. set Page FlowDirectio to RightToLeft
    <ContentPage FlowDirection="RightToLeft"></ContentPage >
  2. Define a RelativeLayout as root container
  3. Define a View(here a label named Source) and set it's position relative to the Parent so the view appears at the right side of page:
<Label Background="Green" WidthRequest="70" HeightRequest="70" x:Name="Source" Text="Source" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White"
                                RelativeLayout.XConstraint = "{ConstraintExpression Type=RelativeToParent,
                                                         Property=Width,
                                                         Factor=0,
                                                         Constant=0}"
                                RelativeLayout.YConstraint ="{ConstraintExpression Type=RelativeToParent,
                                                         Property=Height,
                                                         Factor=0.3,
                                                         Constant=0}" />
  1. Define a second view(here a label named Target) and set it's position relative to the first(Source) View with XConstraint bound to first View X Property :
<Label x:Name="TargetBox" WidthRequest="70" HeightRequest="70" BackgroundColor="Red"  Text="Target" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White"
                     RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView,
                                    ElementName=Source,
                                    Property=X,
                                    Constant=0}"
                     RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,
                                    ElementName=Source,
                                    Property=Y,
                                    Constant=200}"/>

Expected Behavior

the two Views must appears at the same place(Coordinate , position) Horizontally. (because the second view XConstraint is Bound to the first view X property)

Actual Behavior

the second view appears in different position toward to the first view in Horizontal axis.(in fact it's positioned at left side of page)(following Picture)

Basic Information

  • Version with issue:Xamarin.Forms 4.8.0.11
  • Last known good version:
  • IDE:Microsoft Visual Studio 2020 -16.7.0 - Preview 2.0
  • Platform Target Frameworks:
    • iOS: 13.5
    • Android: 9.0
    • UWP:
  • Android Support Library Version:
  • Nuget Packages:Xamarin.Forms 4.8.0.11
  • Affected Devices:

Screenshots

iPAD-RelativeLayout_RTL1

Reproduction Link

Workaround

@hamiddd1980 hamiddd1980 added s/unverified New report that has yet to be verified t/bug 🐛 labels Aug 3, 2020
@hamiddd1980
Copy link
Author

Hi.
I think the problem comes from LayoutChildIntoBoundingRegion() method in Layout class (Line 137):

137 -public static void LayoutChildIntoBoundingRegion(VisualElement child, Rectangle region)
138- {
139-    var parent = child.Parent as IFlowDirectionController;
140-	bool isRightToLeft = false;
141-	if (parent != null && (isRightToLeft = parent.ApplyEffectiveFlowDirectionToChildContainer &&  parent.EffectiveFlowDirection.IsRightToLeft()))
142-		region = new Rectangle(parent.Width - region.Right, region.Y, region.Width, region.Height);
.
.
.
.
178-child.Layout(region);
179-}

in the above code , when View is RightToLeft , it is mirrored to the right side of page in line 142.
Line Number 142 , namely
region = new Rectangle(parent.Width - region.Right, region.Y, region.Width, region.Height);
must be called only for views which are Relative to Parent , not for Views relative to other Views.
In the other words , because in Views relative to other Elements (I call them Source) , the X property is bound to source Element's Left property and RightToLeft Effect is currently applied to Source Views relative to parent (lines 141 and 142) , so it's not required anymore to
"check whether the Relative View is RightToLeft and change it's Rectangle".(for views relative to other views)
it seems that we can define an optional parameter named isViewRelativeToOtherView of type bool (or an Overload version of LayoutChildIntoBoundingRegion() method) . then we can check this parameter in method body and if it's True we should skip line number142.
mentioned method is called from Relaitivelayout class in method LayoutChildren() (Line Number 155) . we can use BoundsConstraint in this method to produce value for isViewRelativeToOtherView .
please examine this procedure and I hope this can help you to correct this bug in first coming release of Xamarin.Forms.
Thank you.

@PureWeen
Copy link
Contributor

PureWeen commented Aug 5, 2020

<RelativeLayout Margin="20">
            <Label Background="Green" WidthRequest="70" HeightRequest="70" x:Name="Source" Text="Source" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White"
                                RelativeLayout.XConstraint = "{ConstraintExpression Type=RelativeToParent,
                                                         Property=Width,
                                                         Factor=0,
                                                         Constant=0}"
                                RelativeLayout.YConstraint ="{ConstraintExpression Type=RelativeToParent,
                                                         Property=Height,
                                                         Factor=0.3,
                                                         Constant=0}" />
            <Label x:Name="TargetBox" WidthRequest="70" HeightRequest="70" BackgroundColor="Red"  Text="Target" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White"
                     RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView,
                                    ElementName=Source,
                                    Property=X,
                                    Constant=0}"
                     RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,
                                    ElementName=Source,
                                    Property=Y,
                                    Constant=200}"/>
        </RelativeLayout>

@PureWeen PureWeen added a/relativelayout and removed s/unverified New report that has yet to be verified labels Aug 5, 2020
@PureWeen PureWeen added the a/rtl label Aug 5, 2020
@hamiddd1980
Copy link
Author

Hi, according to the fact that the Root of this problem is Known and Discovered (as I pointed to it in above Comments) ,so why have you moved this problem from Ready For Work to Needs Estimate ?
I ask this question because I think now it will take a long time to correct this bug.
Thank you.

@hamiddd1980
Copy link
Author

hamiddd1980 commented Aug 12, 2020 via email

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants