8

How to make the parent layout - Box wrap its content in Jetpack compose? The current implementation below fills the entire screen, I only want the Box to wrap around its child - Switch. How do I define wrap content for the Box?

@Composable
fun TestScreen(modifier: Modifier = Modifier) {
    Box(modifier = Modifier.background(Color.Yellow)){
        val switchState = remember { mutableStateOf(true) }
        Switch(
            checked = switchState.value,
            enabled= true,
            onCheckedChange = { switchState.value = it }
        )
    }
}

A Switch inside a Box

z.g.y
  • 5,512
  • 4
  • 10
  • 36
Bullionist
  • 2,070
  • 3
  • 25
  • 42

2 Answers2

6

Box covers entire screen is probably something more sneaky because of Surface with Modifier.fillMaxSize() updates minimum Constraints of TestScreen because it is direct descendent of Surface.

Surface is a Box with propagateMinConstraints: Boolean = true which forces minimum width and height to its direct descendent. This answer explains with examples how it works.

Your Composable is actually as this when parent is not Surface as i mentioned above.

Surface(
    modifier = Modifier.fillMaxSize()
) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(10.dp)
    ) {
        TestScreen()
    }
}

enter image description here

Thracian
  • 43,021
  • 16
  • 133
  • 222
  • 1
    Is there a way to Specify wrap content to the `Box` without wrapping it in a `Surface`+`Column`? – Bullionist Dec 02 '22 at 04:31
  • There are several ways. First, you don't have to give Modifier.fillMaxSize to your Surface. Having no Modifier returns 0 minWidth and 0 minHeight. You don't have use Surface also. You can do same thing with a Box by applying shape, shadow and other Modifiers. I suggest you to check out Constraints section of the answer i posted to be familiar how size is applied with modifiers – Thracian Dec 02 '22 at 04:34
  • Surface only forces minimum Constraints to direct descendant, other descendants are not effected – Thracian Dec 02 '22 at 04:36
  • So there is no way to apply WrapContent on a `Box` as per my question? – Bullionist Dec 02 '22 at 04:37
  • If you use Surface with Modifier.fillMaxSize unfortunately no. propagateMinConstraints = true was a deliberate design. You can google it. I remember seeing and issue why it's set this way – Thracian Dec 02 '22 at 04:40
  • I don't use any `Surface` - only a `Box` as per the sample code in my question. – Bullionist Dec 02 '22 at 04:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/250079/discussion-between-thracian-and-bullionist). – Thracian Dec 02 '22 at 04:42
5

Since you haven't specified on what container/parent composable your posted composable is being called, I can only suggest using Modifier's wrapContentSize.

    Box(
        modifier = Modifier
            .background(Color.Yellow)
            .wrapContentSize() // wrap content height and width
    ){
        val switchState = remember { mutableStateOf(true) }
        Switch(
            checked = switchState.value,
            enabled= true,
            onCheckedChange = { switchState.value = it }
        )
    }

enter image description here

z.g.y
  • 5,512
  • 4
  • 10
  • 36
  • 1
    If your Composable is not direct child of Surface it already doesn't cover entire screen with or without Modifier.wrapContent. If you set Modifier.wrapContent as in OPs question when Box covers entire screen without any size Modifier which only can happen when it has direct parent is Surface you will see that Modifier.wrapContent or any Modifier you set won't work. – Thracian Dec 02 '22 at 04:25
  • Thanks for the answer, however it does not work. The `wrapContentSize` makes the `Switch` centered in the Box as per [this image](https://imgur.com/n2vAkT4) – Bullionist Dec 02 '22 at 04:26
  • Ohh, I haven't encountered this yet!, thank you @Thracian again! – z.g.y Dec 02 '22 at 04:27
  • 1
    Actually Doc @Thracian, your'e giving me an idea from an issue I answered recently about the dialog button resizing (the 75% if you have seen it)… thank you again, I upvoted your answer! – z.g.y Dec 02 '22 at 04:31
  • 1
    You are welcome. You can check out my surface answer. I had this Surface issue several times and finally i ceased forgetting :) – Thracian Dec 02 '22 at 04:31
  • Final quesiton Doc @Thracian, sorry Bullisionist for spamming unrelated topic, do you have an S.O post/answer where you show how to debug placements and measurements? – z.g.y Dec 02 '22 at 04:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/250078/discussion-between-thracian-and-z-y). – Thracian Dec 02 '22 at 04:36