Fudge

    Fudge

    2 years ago
    Is there a way to constrain an element absolutely, without letting it relayout itself to fit within the available space? The use case is to create a component that can swipe between different screens. (I already have it implemented, but the children keep moving around as they're getting constrained) This image illustrates the idea:
    Adam Powell

    Adam Powell

    2 years ago
    Not quite sure I understand
    Fudge

    Fudge

    2 years ago
    More images, then
    Adam Powell

    Adam Powell

    2 years ago
    You can do anything you want in a layout modifier as long as the modifier itself obeys the constraints it was given; you can measure the child element with whatever constraints you like and place it however you like, the parent will only see the modifier's size and frame of reference
    I think we're still missing a
    Modifier.layout {}
    API for defining these quickly without explicitly declaring a LayoutModifier class but it should be coming soon
    Fudge

    Fudge

    2 years ago
    This code snippet produces the behavior I don't want:
    Box(Modifier.width(20.dp)) {
            Text("Foo Bar")
        }
    Are you saying I can achieve this by using some custom layout with
    Layout()
    ?
    Adam Powell

    Adam Powell

    2 years ago
    You can if you want to arrange multiple children, if you only want to modify a single element, write a LayoutModifier instead
    And you can choose to add a clip modifier before it or not, up to you
    Fudge

    Fudge

    2 years ago
    I'll try to figure out how LayoutModifier and co work, thanks
    This is a big interface 😨
    o

    okarm

    2 years ago
    I have never tried Compose, but couldn’t you just set maxLines=1 on the Text widget?But maybe I’m talking out of my butt here.
    Fudge

    Fudge

    2 years ago
    @okarm That might work, but the goal is for this to work for any arbitrary component and without modifying individual existing components
    Text is just an example, this could also be applied to icons
    o

    okarm

    2 years ago
    Ah, yes, I wasn’t sure.
    Adam Powell

    Adam Powell

    2 years ago
    You can ignore everything but the measure method from the interface, the rest has defaults
    The signature is gnarly and that's why it could benefit from a builder
    But it's identical to the signature of the Layout composable except it deals with one element instead of multiple
    Fudge

    Fudge

    2 years ago
    I think the
    measure
    method decides the constraints that are given to the children? What decides what constraints are given to the parent?
    I'm probably misunderstunding though
    Maybe it's the other way around?..
    Ok, I can't seem to figure it out. This is what I have
    private data class CutModifier(
        private val maxWidth: Dp
    ) : LayoutModifier {
    
        override fun MeasureScope.measure(
            measurable: Measurable,
            constraints: Constraints,
            layoutDirection: LayoutDirection
        ): MeasureScope.MeasureResult {
            val placeable = measurable.measure(constraints)
            return layout(maxWidth.toIntPx(), placeable.height) {
                placeable.place(0, 0)
            }
        }
    
    }
    Is this right? It seems like the modifier is not doing anything
    ah, I simply needed to add a clip modifier before, it was so simple...
    And also set the width constraint to infinity
    Adam Powell

    Adam Powell

    2 years ago
    Yep. The constraints param to the measure method is the constraints the parent is measuring you with. You can change those constraints before measuring the modified element and account for those changes in your own sizing and placement.
    So for example, the preferred size modifiers set min/max constraints for the child to the target value, coerced within the parent supplied constraints.