How to transform lazycolumn itself

38 Views Asked by At

I am learning lazycolumn, I can't transform lazycolumn without effecting scrolling.

My code is

var offset by remember { mutableStateOf(Offset.Zero) }
var rotationAngle by remember { mutableFloatStateOf(0f) }
var scale by remember { mutableFloatStateOf(1f) }

val transformableState =
    rememberTransformableState { zoomChange: Float, panChange: Offset, rotationChange: Float ->
        scale *= zoomChange
        offset += panChange
        rotationAngle += rotationChange
    }

LazyColumn(
    verticalArrangement = Arrangement.spacedBy(8.dp),
    modifier = Modifier
        .scale(scale)
        .transformable(
            state = transformableState,
            lockRotationOnZoomPan = false
        )
) {
    items(listOf(0, 1, 2)) {
        Image(
            bitmap = getInitPageImage(
                LocalContext.current,
                it.toString()
            ).asImageBitmap(),
            contentDescription = null,
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.Green)
                .wrapContentSize(
                    align = Alignment.TopCenter,
                    unbounded = true
                )
        )
    }
}

fun getInitPageImage(context: Context, page: String): Bitmap {
    val scale = context.resources.displayMetrics.density

    val width = context.resources.displayMetrics.widthPixels
    val height = context.resources.displayMetrics.heightPixels
    val conf = Bitmap.Config.ARGB_8888

    val result = Bitmap.createBitmap(width, height, conf)
    val canvas = Canvas(result)

    val paintImage = Paint()
    paintImage.color = android.graphics.Color.DKGRAY
    canvas.drawRect(0f, 0f, result.width.toFloat(), result.height.toFloat(), paintImage)

    val paint = Paint()
    paint.color = android.graphics.Color.WHITE
    paint.textSize = 200 * scale
    paint.isAntiAlias = true
    paint.isUnderlineText = false
    paint.textAlign = Paint.Align.CENTER
    canvas.drawText(page, result.width.toFloat() / 2, result.height.toFloat() / 2, paint)

    return result
}

The result is: When I put one finger on lazycolumn and scroll it with a tiny distance, the touch event or what would consume the event and loop do-while the scroll works, then I put the other one finger on it, it would not trigger event because of the loop.

What I expect is: I put the first finger on lazycolumn and scroll it, it would scroll, when I put the second finger on it, I can zoom it in or out, and drag it with offset, after I zoomed in and take one finger away, the least finger can still drag it, even scroll it.

1

There are 1 best solutions below

0
rong holl On

Eureka!

It is simple, which caught me nights and nights, the key is lazyListState

...
val coroutineScope= rememberCoroutineScope()
val lazyListState = rememberLazyListState()
val transformableState =
    rememberTransformableState { zoomChange: Float, panChange: Offset, rotationChange: Float ->
        scale *= zoomChange
        offset += panChange
        rotationAngle += rotationChange
        coroutineScope.launch {
            lazyListState.scrollBy(-panChange.y)
        }
    }

LazyColumn(
    userScrollEnabled = false,
    state = lazyListState,
    ...
){
    ...
}

I think the fling behavior would not be diffcult.