https://kotlinlang.org logo
Title
d

dimsuz

05/03/2022, 1:34 PM
I'm trying to do custom layout inside a Button and it seems I lack some insight into a layout procedure.
Button(
  modifier = Modifier.widthIn(min = 365.dp), 
  onClick = {}
) {
  Layout({ Text("hello") }) { measureables, constraints ->
    println("$constraints")
  }
}
I thought that incoming
constraints
would have minWidth set to
365.dp
, but they are actually
minWidth=0, maxWidth=636.dp
which comes from
Button
parent. What is the correct way to layout button's content with respect to imposed min size on the button?
l

Louis Pullen-Freilich [G]

05/03/2022, 1:38 PM
You haven’t passed
modifier
as a parameter to
Layout
in the code you shared
d

dimsuz

05/03/2022, 3:27 PM
But why should I? this is the modifier for the button, not for its content. For example if I want to apply some border or background modifications, I expect them to go into
Button
and not into its content. Or should I pass 2 modifiers in this case? Never saw this in compose samples though...
l

Louis Pullen-Freilich [G]

05/03/2022, 3:29 PM
Oh sorry, I thought you were trying to build your own
Button
function, I didn’t realize that was a function call inside something else. What is the parent of button in this case? If the parent is making button bigger, then it seems reasonable - you are only setting the min width on button, so it can be forced to be bigger if the parent is measuring it with more space
d

dimsuz

05/03/2022, 3:40 PM
My use case is that I want to make button with say minWidth=200.dp and then I want to have Progress bar aligned to the end of the button an the text centered in the space left.
Button(
  modifier = Modifier.widthIn(200.dp),
  content = {
    Spacer(modifier = Modifier.weight(1f))
    Text("Button")
    Spacer(modifier = Modifier.weight(1f))
    CircleProgressBar()
  }
)
This results in Button which ignores 200.dp and always fills max size. And I don't want to do
requireMinWidth(200.dp)
, because if text is over 200.dp, I want button to expand accordingly.
Same thing if I do a custom layout inside, it never gets minWidth. Maybe I should approach this differently...
l

Louis Pullen-Freilich [G]

05/03/2022, 5:15 PM
Right, the minWidth is applied to the button, not necessarily the content inside the button, since the button has extra padding / can decide how to size the content inside. There’s no guarantee that constraints passed to the component will not be modified when they arrive in layouts inside
If you want the content of the button to have a minimum width of 200.dp, then you should apply that to the
Layout
. And the
Button
will size itself to make space for that
d

dimsuz

05/03/2022, 6:38 PM
Yeah, but the thing is: imagine if this is a some kind of a UiKit component. I want to be able to write
UiKitButton(modifier = Modifier.widthIn(min = 200.dp)) // implemented using material.Button
And then I'd like the
content
which I pass to the
Button
inside
UiKitButton
to be stretched to that
min
. I have no way to extract those "200.dp" from the modifier to pass it to the content. Another option is to use
UiKitButton(minWidth = 200.dp)
But I don't like it much, because I would prefer to deliver layout constraints using modifiers.
z

Zach Klippenstein (he/him) [MOD]

05/10/2022, 3:00 PM
It's entirely up to a layout whether it wants to pass the min constraints it receives itself to its children. It looks like Button’s layout is not doing this. The only way to change that behavior would be to modify Button.
d

dimsuz

05/12/2022, 11:25 AM
I see, thanks! Will write my own layout then.