Search code examples
androidkotlinandroid-jetpack-composeandroid-jetpack

Jetpack compose screenshot image


I'm trying to screenshot the below composable.

It currently nearly works, however the players on the screen's new position after they've been dragged don't appear in the screenshot.

The FourFourTwo and FourFiveOneFormation composables contain the Player composables.

var capturingViewBounds by remember { mutableStateOf<Rect?>(null) }

val context = LocalContext.current
var view = LocalView.current

Column(
        modifier = Modifier
            .padding(top = 8.dp)
            .height(390.dp)
            .width(300.dp)
            .onGloballyPositioned {
                capturingViewBounds = it.boundsInRoot()
            },
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

        when (currentFormation) {

            1 -> {
                FourFourTwoFormation(
                    state = state,
                    events = events
                )
            }

            2 -> {
                FourFiveOneFormation(
                    state = state,
                    events = events
                )
            }
        }

val bounds = capturingViewBounds ?: return@clickable
bitmap = Bitmap.createBitmap(
    bounds.width.roundToInt(), bounds.height.roundToInt(),
    Bitmap.Config.ARGB_8888
).applyCanvas {
    translate(-bounds.left, -bounds.top)
    view.draw(this)
}

My player composable looks like this

Column(
    modifier = Modifier
        .offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
        .pointerInput(Unit) {
            detectDragGestures { change, dragAmount ->
                change.consumeAllChanges()
                offsetX.value = (offsetX.value + dragAmount.x)

                offsetY.value = (offsetY.value + dragAmount.y)
            }
        }

I want the screenshot to look like the left, but at the moment looks like the right

enter image description here enter image description here


Solution

  • This looks like a compose bug: seems like view.draw ignores offset with IntOffset as well as graphicsLayer. I've reported it, please star it to bring more attention.

    Fortunately, it works fine with offset by dp, so you can use it that way for now:

    val density = LocalDensity.current
    // ...
    .offset(
        x = with(density) { offsetX.value.toDp() },
        y = with(density) { offsetY.value.toDp() },
    )