androidandroid-jetpack-composepinchzoom

Is there a way to implement Pinch to Zoom In/Zoom Out on a Jetpack Compose Text element without it overflowing the screen?


I'm using the Zoomable library to Zoom In/Zoom Out a Text element in Jetpack Compose.

The problem is that when I enlarge the text size, the content overflows the limits of the screen.

Code:

@Composable
fun TextZoomable(text: AnnotatedString, onTap: (Offset) -> Unit) {
    val zoomState = rememberZoomState()
    Box(
        modifier = Modifier
            .fillMaxSize()
            .zoomable(
                zoomState = zoomState,
                onTap = onTap
            ),
    ) {
        Text(
            text = text,
        )
    }
}

Contextual use:

var text = AnnotatedString("")
//text is my some large content ...

Column {
    TextZoomable(onTap = onTap, text = text)
}

This is a screenshot before zooming out:

enter image description here

When I Zoom Out, this happens:

enter image description here

Is there a way to Zoom In/Out a Text element without it overflowing the screen boundaries?

Would it be possible to do this without using third-party libraries?


Solution

  • The Zoomable Composable will not work in this case, as it performs any zoom on the graphical layer. What you actually want to do is to transform the value assigned as fontSize of your Text Composable.

    You can use the transformable Modifier to achieve this:

    @Composable
    fun ZoomableText() {
    
        var textScale by remember { mutableFloatStateOf(1f) }
        val zoomState = rememberTransformableState { zoomChange, _, _ ->
            textScale *= zoomChange
        }
    
        Text(
            modifier = Modifier
                .fillMaxSize()
                .transformable(state = zoomState, lockRotationOnZoomPan = true)
                .verticalScroll(rememberScrollState()),
            text = LoremIpsum(2000).values.joinToString(),
            fontSize = (textScale * 16).sp,  // set base text size as needed
            lineHeight = (textScale * 16).sp  // should be same or more than fontSize
        )
    }
    

    Also make sure you are using the latest Compose Libraries, there were bugs in older library versions when combining transformable with verticalScroll. If you are using Compose BOM, use as of 01/2025

    composeBom = "2025.01.01"
    

    Output:

    Screen Recording