0

I am making my own custom ResizableBox composable. It just shows a red box with a handle at the bottom end, and when I drag the handle, it resizes the box.

This kind of works:

@Composable
fun ResizableBox(
    modifier: Modifier = Modifier,
) {
    var size by remember { mutableStateOf(DpSize(200.dp, 200.dp)) }

    Box(modifier = Modifier
        .background(Color.Red)
        .then(modifier)
        .size(size)
    ) {
        Handle(modifier = Modifier.align(Alignment.BottomEnd)) {
            size = DpSize(size.width + it.x.dp, size.height + it.y.dp)
        }
    }
}

The thing is that I am trying to use .then(modifier) to allow the caller to set a default value for size (instead of my hardcoded default 200x200). But when I set .size() from the caller, then the size never gets updated (presumably because I change it in the inner modifier, but the first value being set is in the outer modifier).

In other words:

// This works with a box starting with size 200x200
ResizableBox()

// This creates a box with size 100x150, but the handle fails to resize the box
ResizableBox(modifier = Modifier.size(width = 100.dp, height = 150.dp))

I think I am missing something regarding how I should compose the two modifiers together. How can I make it work?

JonasVautherin
  • 7,297
  • 6
  • 49
  • 95
  • 1
    When you chain `Modifier.size(50.dp).size(100.dp)` first one is used. You can't chain size modifiers except with requiredSizeX and wrapContent in some situations. This allows default sizes to be assigned if dev doesn't assign a Modifier with size Modifier. You can refer [this answer](https://stackoverflow.com/questions/71677339/why-are-the-modifier-sizes-not-overwritten) and [this](https://stackoverflow.com/a/73258726/5457853) for more details. – Thracian May 02 '23 at 06:28

1 Answers1

3

There are many ways how to achieve your solution but I think the simplest would be to pass the initial size as a parameter and omit the inner modifier if you can.

As for chaining the Modifier.size goes, I think it works the way only the first one will be applied and other modifiers of the same type will be ignored.

Your code with my proposal could look like this:

@Composable
fun ResizableBox(
    modifier: Modifier = Modifier,
    initialSize: DpSize = DpSize(200.dp, 200.dp),
) {
    var size by remember { mutableStateOf(initialSize) }

    Box(
      modifier = Modifier
        .background(Color.Red)
        .size(size)
    ) {
        Handle(
           modifier = Modifier.align(Alignment.BottomEnd)
        ) {
            size = DpSize(size.width + it.x.dp, size.height + it.y.dp)
        }
    }
}

Hope this helps!

renybytes_
  • 161
  • 2