Jetpack Compose 实现图片缩放功能

238 阅读1分钟

效果演示

先给大伙看看手势操作的效果

image_scale 00_00_00-00_00_30.gif

相关源码

代码更是比用 Kotlin/Java 实现的方式简单多了

package com.lujianfei.kotlindemo.ui.imagescale

/**
 * Author: lujianfei
 * Date: 2023/12/29 13:50
 * Description:
 */
@ExperimentalUnitApi
class ImageScaleActivity:AppCompatActivity() {

    companion object {
        fun start(context: Context) {
            context.startActivity(Intent(context, ImageScaleActivity::class.java))
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Page(
                leftIcon = R.drawable.ic_back,
                onLeftClick = {
                    onBackPressed()
                },
                title = "图片缩放",
                onRightClick = {
                },
                rightText = null
            ) {
                Content()
            }
        }
    }

    @OptIn(ExperimentalMaterialApi::class)
    @ExperimentalUnitApi
    @Composable
    @Preview(showSystemUi = true)
    fun Content() {
        /**
         * 缩放比例
         */
        var scale by remember { mutableFloatStateOf(1f) }
        /**
         * 监听手势状态变换
         */
        val state = rememberTransformableState(onTransformation = { zoomChange, _, _ ->
            scale = (zoomChange * scale).coerceIn(1f, 5f)
        })
        Box(modifier = Modifier.fillMaxWidth().fillMaxHeight(), contentAlignment = Alignment.Center) {
            Image(painter = painterResource(id = R.mipmap.ic_launcher),
                contentDescription = "123",
                contentScale = ContentScale.Fit,
                modifier = Modifier
                    .width(200.dp)
                    .height(200.dp)
                    .transformable(state = state)
                    .graphicsLayer {  //布局缩放、旋转、移动变换
                        scaleX = scale
                        scaleY = scale
                    }
                    .pointerInput(Unit) {
                        detectTapGestures(
                            onDoubleTap = {
                                scale = if (scale <= 1f) {
                                    2f
                                } else {
                                    1f
                                }
                            }, onTap = {})
                    })
        }
    }
}