Icyrockton
Icyrockton

Reputation: 23

how to use LayoutAlign in jetpack compose

Column(LayoutSize.Fill) {
        Box(
                modifier = LayoutSize(20.dp) + LayoutSize.Min(40.dp, 40.dp) + LayoutAlign.TopCenter,
                backgroundColor = Color.Blue
        )
        Box(
                LayoutSize(50.dp) + LayoutSize.Fill + LayoutAlign.CenterVertically,
                backgroundColor = Color.Blue
        )
    }

I try this sample LayoutAlign

but no rectangles are shown

Upvotes: 1

Views: 326

Answers (1)

Maciej Ciemięga
Maciej Ciemięga

Reputation: 10715

Quick Answer

This sample is broken due to the wrong order of modifiers. Order of modifiers is very important in Compose. This code would work as expected:

Box(
    LayoutSize.Min(40.dp, 40.dp) + LayoutAlign.TopCenter + LayoutSize(20.dp),
    backgroundColor = Color.Blue
)

Box with color background example

Why it doesn't work in the original sample?

LayoutAlign aligns the content within bounds, when content size is smaller than its bounds. What it does under the hood is resetting min size constraint (minWidth, minHeight, or both, depending on alignment direction) allowing the content to be smaller and occupy its preferred size.

Box with just background color doesn't provide any preferred intrinsic size of its content. If it's allowed to be as small as 0dp x 0dp - it will be.

In the correct example, this is how constraints are modified under the hood:

  1. LayoutSize.Min(40.dp, 40.dp) reserves at least 40dp bounds
    Contraints: minWidth = 40dp, maxWidth = infinity, minHeight = 40dp, maxHeight = infinity
  2. LayoutAlign.TopCenter applies alignment and resets min size constraints for both directions
    Constraints: minWidth = 0dp, maxWidth = infinity, minHeight = 0dp, maxHeight = infinity
  3. LayoutSize(20.dp) orders the content to be exactly 20dp big. minWidth and minHeight are important here, without it the content of the Box would be measured as 0dp x 0xp.
    Constraints: minWidth = 20dp, maxWidth = 20dp, minHeight = 20dp, maxHeight = 20dp.

Without the last step the Box content will be measured as 0dp x 0dp. This is what's happening in the original sample. The box is technically aligned/positioned correctly within 40dp, but it's invisible because its size is 0dp x 0dp.

Using LayoutAlign on elements that provide its own preferred size

Keep in mind that if the element knows how to measure its content or provides some preferred size, then it will work just fine even if we won't set any size after applying the LayoutAlign modifier.

Example:

Text("Text",
    modifier = LayoutSize.Min(40.dp, 40.dp) + LayoutAlign.TopCenter,
    style = TextStyle(fontSize = 8.sp)
)

Text example

Upvotes: 2

Related Questions