能自己做效果图的网站,集团网站建设方案,怎么做谷歌这样的网站,国际新闻软件哪个好Compose手势
本文链接#xff1a;
点击 拖动 滑动
锚点
Compose Drag 拖动原理
Compose Drag 拖动原理:等待第一次按下 挂起 // UI展现出来的时候#xff0c;这个while循环就已经在等待第一次按下了。事件 - 恢复判断拖动合法性合法onDragStartonDragonDragEndforEa…Compose手势
本文链接
点击 拖动 滑动
锚点
Compose Drag 拖动原理
Compose Drag 拖动原理:等待第一次按下 挂起 // UI展现出来的时候这个while循环就已经在等待第一次按下了。事件 - 恢复判断拖动合法性合法onDragStartonDragonDragEndforEachGesture{awaitPointerEventScope{val down awaitFirstDown()onDragStart.invokeonDragonDragCancel // 看条件onDragEnd // 看条件}
}变换手势原理
功能代码
Composable
fun TransformGestureDemo() {var boxSize 100.dpvar offset by remember { mutableStateOf(Offset.Zero) }var ratationAngle by remember { mutableStateOf(0f) }var scale by remember { mutableStateOf(1f) }Box(Modifier.fillMaxSize(), contentAlignment Alignment.Center) {Box(Modifier.size(boxSize).rotate(ratationAngle) // 需要注意offset与rotate的调用先后顺序.scale(scale).offset {IntOffset(offset.x.roundToInt(), offset.y.roundToInt())}.background(Color.Green).pointerInput(Unit) {detectTransformGestures(panZoomLock true, // 平移或放大时是否可以旋转// 该回调会在内部被调用onGesture { centroid: Offset, pan: Offset, zoom: Float, rotation: Float -offset panscale * zoomratationAngle rotation})})}
}源码
UI页面展示的时候就在等待第一个事件到来挂起
suspend fun PointerInputScope.detectTransformGestures(panZoomLock: Boolean false,onGesture: (centroid: Offset, pan: Offset, zoom: Float, rotation: Float) - Unit
) {// while循环处理事件forEachGesture {awaitPointerEventScope {// 省略xxx// 等待第一次按下awaitFirstDown(requireUnconsumed false)do {val event awaitPointerEvent() // 点击事件val canceled event.changes.fastAny { it.isConsumed }if (!canceled) {val zoomChange event.calculateZoom() // 变换值val rotationChange event.calculateRotation() // 变换值val panChange event.calculatePan() // 变换值// 省略xxx// 调用回调我们自己实现的方法onGesture(centroid, panChange, zoomChange, effectiveRotation)}} while (!canceled event.changes.fastAny { it.pressed })}}
}点击事件分发
1、ComposeView装载AndroidComposeView
2、补充知识点onTouchEvent返回true代表消费完了从上到下从下到上 U型结构自上而下
3、AndroidComposeView.java#dispatchTouchEvent
dispatchTouchEvent()
--val processResult handleMotionEvent(motionEvent)--pointerInputEventProcessor.process(pointerInputEvent, xxx)--root.hitTest() // flutter有个方法hitTest一批人开发用于点击测试/点击命中--hitPathTracker.addHitPath()// 加入到【候选人名单】中--hitPathTracker.dispatchChanges() // 处理两种事件三种事件会分发三次--root.dispatchMainEventPass()--children.forEach {dispatched it.dispatchMainEventPass() || dispatched} // 点击测试从父节点到子节点--pointerInputNode.onPointerEvent(event, PointerEventPass.Main, size)--dispatchPointerEvent(pointerEvent, pass)--it.offerPointerEvent(pointerEvent, pass)--resume(event) // 恢复 awaitFirstDown()第一次按下会挂起。 上面变换、拖拽、点击的awaitFirstDown()--root.dispatchFinalEventPass()
--if (processResult.anyMovementConsumed) parent.requestDisallowInterceptTouchEvent(true)
--return processResult.dispatchedToAPointerInputModifierCompose事件
1、事件传递从上至下
rootlayoutNode1layoutNode2layoutNode3
2、候选人机制
3个Node都包含点击的这个点Compose会把包含了这个点的都加入到候选人名单共四个不想走两遍
3、对名单中候选人进行判定不能处理的就从名单剔除 Flutter也是如此
从layoutNode3最上层的优先判定
4、添加到候选人名单的条件名单一般很少几个
包含点添加了事件
5、Compose事件类型会分发两个线路main和final
initmainfinal
6、Root是什么
LayoutNode根节点
AndroidComposeView.java对root初始化override val root LayoutNode().also {it.measurePolicy RootMeasurePolicyit.density density// Composed modifiers cannot be added here directlyit.modifier Modifier.then(semanticsModifier).then(rotaryInputModifier).then(_focusManager.modifier).then(keyInputModifier)}