Does Compose have a Modifier that is equivalent to...
# compose
l
Does Compose have a Modifier that is equivalent to SwiftUI’s id? I have a part of my app that renders pixel data into an IntArray, and I use nativeCanvas to render this to a composable. I don’t want to have to re-allocate this array every time it re-renders, but I do have a variable that I can guarantee will change if the pixels change. I would like changes in this variable to cause recomposition of my Canvas. I know that I can just to a meaningless read of the variable, but I’d like something more clear.
Hypothetical example:
Copy code
@Composable
fun MyCustomView(pixels: IntArray, someVariable: Int) {
    Canvas() {
        val bitmap = Bitmap.createBitmap(size.width.toInt(), size.height.toInt(),
            Bitmap.Config.ARGB_8888)
        bitmap.copyPixelsFromBuffer(IntBuffer.wrap(pixels))
        drawIntoCanvas {  canvas ->
            someVariable //meaningless read to force recomposition
            val native = canvas.nativeCanvas
            native.drawBitmap(bitmap, 0f, 0f, paint.asFrameworkPaint())
        }
    }
}
I’d like to be able to apply Modifier.id(someVariable) or something to indicate that pixels depends on someVariable.
r
would
val bitmap = remember(someVariable) { ... }
do what you want?
z
l
I had thought of doing a remember calculation, but calculating the pixel buffer depends on more than just someVariable (but I do know that someVariable is guaranteed to change if the pixel buffer changes) and updates to both need to be independent of composition timing. I’ll definitely check out key.
Key looks like it could do what I’m looking for. I’ll have to try it out.
Thinking about it, remember should also work, since it reads someVariable.
r
If all you need to be able to do is not skip creating a bitmap every time
someVariable
changes, then either should work. It doesn't matter how many additional reads you do in the calculation block, the only things that cause recalculation are what you pass in for the
key
.
l
When you say ‘key’, are you referring to the key method, or the parameters of the composable? I want to make sure I understand what causes recomposition properly.
r
I was referring to
remember
, but the same concept applies to the
key()
function.
And probably why it's named the same as `remember()`'s args
l
That makes sense. I guess I could use
Copy code
val bitmap = remember(someVariable) { Bitmap.createBitmap(size.width.toInt() }
to get a state read of someVariable along with a comment explaining why I don’t use the value in the remember block.
Currently, there’s no alpha, so I guess I could also use remember to avoid allocating the Bitmap. There’s no need to re-allocate each time, especially if I’m going out of my way to avoid allocating the pixel buffer.
z
Since you’re only using it in the draw phase, you could also use
rememberUpdatedState
+ `drawWithCache`:
Copy code
val updatedSomeVariable by rememberUpdatedState(someVariable)
Box(Modifier.drawWithCache {
  val bitmap = createBitmap(updatedSomeVariable…)
  onDrawBehind {
    // draw code here
  }
}
That’s really only useful if you’re also reading other state that can change independently from composition, since it wouldn’t require always recomposing to re-draw.