Jetpack Compose 双指拖拽实现详解
九狼 人气:0Modifier.offset
Compose遇到一个浏览图片的功能,双指放大和缩小
Modifier的offset可以偏移内容。偏移量可以是正的,也可以是非正的。应用偏移只会更改内容的位置,而不会影响其大小测量。
offset由于用户交互而发生变化的偏移。它避免了在偏移量发生变化时进行重新编译,还添加了一个图形层,以防止在偏移量发生变化时对上下文进行不必要的重画。
graphicsLayer
使内容绘制到绘制层中的元素。绘图层可以与父层分开失效。当内容独立于上面的任何内容进行更新时,应使用graphicsLayer,以最小化无效内容。
graphicsLayer可以用于对内容应用各种效果
- 缩放(scaleX、scaleY)
- 旋转(rotationX、rotationY、rotationZ)
- 不透明度(alpha)
- 阴影(shadowElevation、shape)
- 剪裁(clip、shape)
- 以及使用Renderefect更改层的结果。
官方说,如果提供非零阴影高程,并且传递的形状为凹面,则阴影将不会在小于10的Android版本上绘制。
还有小于1.0f的alpha值会将其内容隐式剪裁到其边界。这是因为创建了一个中间合成层,以便在使用所需的alpha将内容绘制到目标之前,先将内容渲染到first中。该层的大小与配置该修改器的可组合对象的边界一致,这些边界之外的内容将被忽略。
Modifier.pointerInput
用于处理修改元素区域内的指针输入。 PointerInputScope或AwaitPointerEventScope上的扩展函数可以定义为执行更高级别的手势检测。指针输入处理块将被取消,并在指针输入用不同的键1重新组合时重新启动。
PointerInputScope.detectTransformGestures
可以用于旋转、平移和缩放的手势检测器。。当发生任何旋转、缩放或平移时,将调用OnGeture,以度为单位传递旋转角度,以像素为单位放大比例因子并以偏移量平移。
逻辑解释
定义4个变量
var angle by remember { mutableStateOf(0f) }//旋转的角度 var zoom by remember { mutableStateOf(1f) }//缩放 var offsetX by remember { mutableStateOf(0f) }//X轴偏移量 var offsetY by remember { mutableStateOf(0f) }//X轴偏移量
offset
Modifier .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
传入graphicsLayer里面
.graphicsLayer( scaleX = zoom, scaleY = zoom, rotationZ = angle )
监听手势
接着就是要监听手势,拿到手势的滑动返回的值让mutableStateOf告诉graphicsLayer刷新UI
.pointerInput(Unit) { detectTransformGestures( onGesture = { _, pan, gestureZoom, gestureRotate -> angle += gestureRotate zoom *= gestureZoom offsetX += pan.x offsetY += pan.y } ) }
图片的话加个Image就可以了,我在这里用背景色代替
background(Color.Cyan)
完整代码
@Composable private fun TransformGestures() { var angle by remember { mutableStateOf(0f) } var zoom by remember { mutableStateOf(1f) } var offsetX by remember { mutableStateOf(0f) } var offsetY by remember { mutableStateOf(0f) } Box( Modifier .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) } .graphicsLayer( scaleX = zoom, scaleY = zoom, rotationZ = angle ) .background(Color.Cyan) .pointerInput(Unit) { detectTransformGestures( onGesture = { _, pan, gestureZoom, gestureRotate -> angle += gestureRotate zoom *= gestureZoom offsetX += pan.x offsetY += pan.y } ) } .fillMaxSize() ) }
效果图
加载全部内容