Android Jetpack Compose:如何将图像缩放到;方框“;?

Android Jetpack Compose:如何将图像缩放到;方框“;?,android,android-jetpack-compose,Android,Android Jetpack Compose,我将在一个框内构建一个可缩放的图像视图,如第一个屏幕截图。但当我放大图像时,它会跳出框外。有没有办法缩放图像,但保持大小?没有视图或片段,只有框似乎是不够的。我希望图像会变大,但仍然留在红色框内,但放大后我得到了第二张截图 多亏了nglauber和Amirhosein,我得到了最终的解决方案,在一个“盒子”(固定区域)内同时具有缩放和拖动功能,下面的代码作为新的屏幕截图,如下所示 val imageBitmap = imageResource(id = R.drawable.

我将在一个框内构建一个可缩放的图像视图,如第一个屏幕截图。但当我放大图像时,它会跳出框外。有没有办法缩放图像,但保持大小?没有
视图
片段
,只有
似乎是不够的。我希望图像会变大,但仍然留在红色框内,但放大后我得到了第二张截图

多亏了nglauber和Amirhosein,我得到了最终的解决方案,在一个“盒子”(固定区域)内同时具有缩放和拖动功能,下面的代码作为新的屏幕截图,如下所示

        val imageBitmap = imageResource(id = R.drawable.android)
        Image(
            modifier = Modifier
                .preferredSize(400.dp, 300.dp)
                .clip(RectangleShape)
                .zoomable(onZoomDelta = { scale.value *= it })
                .rawDragGestureFilter(
                    object : DragObserver {
                        override fun onDrag(dragDistance: Offset): Offset {
                            translate.value = translate.value.plus(dragDistance)
                            return super.onDrag(dragDistance)
                        }
                    })
                .graphicsLayer(
                    scaleX = scale.value,
                    scaleY = scale.value,
                    translationX = translate.value.x,
                    translationY = translate.value.y
                ),
            contentDescription = null,
            bitmap = imageBitmap
        )

只需在
图像
上设置
可缩放
rawDragGestureFilter
,而不是

@Preview
@Composable
fun Zoomable(){
val scale = remember { mutableStateOf(1f) }
val translate = remember { mutableStateOf(Offset(0f, 0f)) }

Box(
    modifier = Modifier.preferredSize(300.dp)

) {
    val imageBitmap = imageResource(id = R.drawable.cover)
    Image(
        modifier = Modifier
            .zoomable(onZoomDelta = { scale.value *= it })
            .rawDragGestureFilter(
                object : DragObserver {
                    override fun onDrag(dragDistance: Offset): Offset {
                        translate.value = translate.value.plus(dragDistance)
                        return super.onDrag(dragDistance)
                    }
                })
            .graphicsLayer(
                scaleX = scale.value,
                scaleY = scale.value,
                translationX = translate.value.x,
                translationY = translate.value.y
            ),
        contentDescription = null,
        bitmap = imageBitmap
    )
  }
}

这是我的解决方案。。。可能对某人有帮助

@Composable
有趣的ZoomableImage(){
val scale=记住{mutableStateOf(1f)}
val rotationState=记住{mutableStateOf(1f)}
盒子(
修饰语=修饰语
.clip(矩形形状)//剪辑框内容
.fillMaxSize()//提供所需的大小。。。
.背景(颜色.灰色)
.pointerInput(单位){
检测转移检测{质心、平移、缩放、旋转->
scale.value*=缩放
rotationState.value+=旋转
}
}
) {
形象(
修饰语=修饰语
.align(Alignment.Center)//将图像集中到框中
.杀戮者(
//添加一些缩放限制(最小50%,最大200%)
scaleX=maxOf(.5f,minOf(3f,scale.value)),
scaleY=maxOf(.5f,minOf(3f,scale.value)),
rotationZ=rotationState.value
),
contentDescription=null,
画家=画家资源(R.drawable.dog)
)
}
}

不推荐使用zoomable,可以使用
PointerInputScope.DetectTransferMgestures

@Composable
fun ImagePreview(link: String) {
    Box(modifier = Modifier.fillMaxSize()) {
        var angle by remember { mutableStateOf(0f) }
        var zoom by remember { mutableStateOf(1f) }
        var offsetX by remember { mutableStateOf(0f) }
        var offsetY by remember { mutableStateOf(0f) }

        CoilImage(
            data = link,
            contentDescription = "image",
            contentScale = ContentScale.Fit,
            modifier = Modifier
                .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
                .graphicsLayer(
                    scaleX = zoom,
                    scaleY = zoom,
                    rotationZ = angle
                )
                .pointerInput(Unit) {
                    detectTransformGestures(
                        onGesture = { _, pan, gestureZoom, gestureRotate ->
                            angle += gestureRotate
                            zoom *= gestureZoom
                            val x = pan.x * zoom
                            val y = pan.y * zoom
                            val angleRad = angle * PI / 180.0
                            offsetX += (x * cos(angleRad) - y * sin(angleRad)).toFloat()
                            offsetY += (x * sin(angleRad) + y * cos(angleRad)).toFloat()
                        }
                    )
                }
                .fillMaxSize()
        )
    }
}

谢谢您的回复,但它仍然与您的更改一样,在放大时会跳出框外。您是否为
框设置了静态大小
?是的,我甚至会将您的代码复制到我的项目中,但它仍然可以工作。它对你有用吗,在盒子里放大?我用的是Jetpack Compose
1.0.0-alpha11
。我知道为什么了。我把
放在
中,这就是它停止工作的原因。如果只是一个框作为
根布局,它就可以工作。但是仅仅因为把它放在另一个布局中而破坏
仍然没有任何意义。它对我来说很有效,甚至把它放在
或其他布局中。谢谢
.clip(长方形)
是我错过的关键点!您的版本仅用于缩放,但不用于拖动。