Skip to content

Instantly share code, notes, and snippets.

@PureWeen
Last active March 30, 2020 20:13
Show Gist options
  • Save PureWeen/3f967592a21b0d16f82e0773c15d19f1 to your computer and use it in GitHub Desktop.
Save PureWeen/3f967592a21b0d16f82e0773c15d19f1 to your computer and use it in GitHub Desktop.
Fused Layout

Let's you base all layout measurements relatively against the layout properties of other views

Properties you can use to calculate against

public double X { get; set; } 
public double Width { get; set; } 
public double Right { get; set; } 
public double Left { get; set; } 
public double Y { get; set; } 
public double Height { get; set; }
public double Baseline { get; set; }			
public double Top { get; set; } 
public double Bottom { get; set; } 
public Point Center { get; set; } 
public double CenterX { get; set; } 
public double CenterY { get; set; } 
public Size Size { get; set; }

Examples

Full set of Unit tests here https://github.com/xamarin/Xamarin.Forms/blob/FusedLayout/Xamarin.Forms.Core.UnitTests/FusedLayoutTests.cs

// all of these views have the height and width already set
// right bottom align view 1
FusedLayout.AddFusion(view1, FuseProperty.Right, new Fusion(fusedLayout).Right);
FusedLayout.AddFusion(view1, FuseProperty.Bottom, new Fusion(fusedLayout).Bottom);

// align the center of view2 to the center of view 1
FusedLayout.AddFusion(view2, FuseProperty.Center, new Fusion(view1).Center);

// align the right edge of view3 to the left edge of view 2 and the bottom of view 3 to the bottom of the layout
FusedLayout.AddFusion(view3, FuseProperty.Right, new Fusion(view2).Left);
FusedLayout.AddFusion(view3, FuseProperty.Bottom, new Fusion(fusedLayout).Bottom);

// place view 4 on the bottom of the fused layout 
// set the right edge of view 4 to the left edge of view 3 + the width of view2
FusedLayout.AddFusion(view4, FuseProperty.Bottom, new Fusion(fusedLayout).Bottom);
FusedLayout.AddFusion(view4, FuseProperty.Right, new Fusion(view3).Left.Add(new Fusion(view2).Width));

STacking Views

var view1fusion = new Fusion(view1).Height;
var view2fusion = new Fusion(view2).Height.Add(3);

// align view 1 to the top of fusion view
FusedLayout.AddFusion(view1, FuseProperty.Top, 0);

// align the top of view2 to the calculation above (view1 height)
FusedLayout.AddFusion(view2, FuseProperty.Top, view1fusion);

// align the top of view3 to the height of view1 + height of view2 + 3
FusedLayout.AddFusion(view3, FuseProperty.Top, view1fusion.Add(view2fusion));

Conditional layouts that allow for dynamic content

// setup basic fuse layout
FusedLayout.AddFusion(view1, FuseProperty.Top, 0);
FusedLayout.AddFusion(view1, FuseProperty.Left, 0);
FusedLayout.AddFusion(view2, FuseProperty.Top, 0);
FusedLayout.AddFusion(view2, FuseProperty.Left, new Fusion(view1).Right);
FusedLayout.AddFusion(container, FuseProperty.Width, new Fusion(fusedLayout).Width);

// create a conditional set that will switch between different layout rules 
var targetWrapperSet = new ConditionalTargetWrapperSet(view3);

// only activate these rules if the width of the container is >= 60 which will cause view3 to layout to the right
// because it's landscape so there is enough room
ConditionalTargetWrapper landscape = 
    targetWrapperSet.AddConditionalSet(() => (FusedLayout.GetSolveView(container).Width >= 60));

// align view3 to the top of the fused layout and place the left edge of view3 on the right edge of view 2
landscape.AddFusion(FuseProperty.Top, new Fusion(fusedLayout).Top);
landscape.AddFusion(FuseProperty.Left, new Fusion(view2).Right);


// only activate these rules if the width of the container is <= 60 which will flow view 3 below view 1 because there isn't enough width
ConditionalTargetWrapper portrait =
    targetWrapperSet.AddConditionalSet(() => !(FusedLayout.GetSolveView(container).Width >= 60));

// align view3 to the bottom of view 1 and place it on the left side of the fused layout
portrait.AddFusion(FuseProperty.Top, new Fusion(view1).Bottom);
portrait.AddFusion(FuseProperty.Left, new Fusion(fusedLayout).Left);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment