Skip to content

Commit 90b6fa4

Browse files
author
iOrchid
committed
copy形式摘选需要的学习代码
1 parent 653ca12 commit 90b6fa4

File tree

17 files changed

+3820
-0
lines changed

17 files changed

+3820
-0
lines changed

compose/src/main/java/org/zhiwei/compose/model/Screen.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,18 @@ import org.zhiwei.compose.screen.gesture.SwipeScroll_Screen
2121
import org.zhiwei.compose.screen.gesture.TapDragGestures_Screen
2222
import org.zhiwei.compose.screen.gesture.TouchImage_Screen
2323
import org.zhiwei.compose.screen.gesture.TransformGestures_Screen
24+
import org.zhiwei.compose.screen.graphics.BeforeAfterScreen
2425
import org.zhiwei.compose.screen.graphics.BlendMode_Screen
2526
import org.zhiwei.compose.screen.graphics.CanvasBasic_Screen
2627
import org.zhiwei.compose.screen.graphics.CanvasPathEffect_Screen
2728
import org.zhiwei.compose.screen.graphics.CanvasPathOperations_Screen
2829
import org.zhiwei.compose.screen.graphics.CanvasPath_Screen
30+
import org.zhiwei.compose.screen.graphics.Chart_Screen
2931
import org.zhiwei.compose.screen.graphics.MultiColorDrawable_Screen
32+
import org.zhiwei.compose.screen.graphics.NeonGlowEffect_Screen
33+
import org.zhiwei.compose.screen.graphics.Others_Screen
34+
import org.zhiwei.compose.screen.graphics.RainbowBorder_Screen
35+
import org.zhiwei.compose.screen.graphics.ShimmerEffect_Screen
3036
import org.zhiwei.compose.screen.layout_state.ConstraintLayout_Screen
3137
import org.zhiwei.compose.screen.layout_state.Constraints_Screen
3238
import org.zhiwei.compose.screen.layout_state.CustomModifier_Screen
@@ -224,6 +230,30 @@ internal object GraphicsScreenUIs {
224230
"MultiColorDrawable",
225231
"演示图形blendMode多色混合的模式效果。"
226232
) { MultiColorDrawable_Screen(modifier) },
233+
CourseItemModel(
234+
"ChartDemos",
235+
"演示图表相关的绘制。"
236+
) { Chart_Screen(modifier) },
237+
CourseItemModel(
238+
"BeforeAfter",
239+
"一个自动切换上下层变化的控件演示demo,变化前后是不同的控件。"
240+
) { BeforeAfterScreen(modifier) },
241+
CourseItemModel(
242+
"ShimmerEffect",
243+
"演示shimmer加载效果的使用,区分同步加载和变化加载。"
244+
) { ShimmerEffect_Screen(modifier) },
245+
CourseItemModel(
246+
"RainbowBorder",
247+
"演示七彩虹的渐变色的描边效果,并且可以动态滚动。"
248+
) { RainbowBorder_Screen(modifier) },
249+
CourseItemModel(
250+
"NeonGlowEffect",
251+
"一种高斯模糊效果blur的实线方式。"
252+
) { NeonGlowEffect_Screen(modifier) },
253+
CourseItemModel(
254+
"OthersScreen",
255+
"零散的其他一些效果演示,比如挖空、图片缩放、水滴融合效果等。"
256+
) { Others_Screen(modifier) },
227257
)
228258
}
229259

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package org.zhiwei.compose.screen.graphics
2+
3+
import androidx.compose.foundation.gestures.*
4+
import androidx.compose.ui.input.pointer.*
5+
import kotlinx.coroutines.coroutineScope
6+
import kotlinx.coroutines.delay
7+
import kotlinx.coroutines.launch
8+
9+
/**
10+
* Reads [awaitFirstDown], and [awaitPointerEvent] to
11+
* get [PointerInputChange] and motion event states
12+
* [onDown], [onMove], and [onUp].
13+
*
14+
* To prevent other pointer functions that call [awaitFirstDown] or [awaitPointerEvent]
15+
* (scroll, swipe, detect functions)
16+
* receiving changes call [PointerInputChange.consume] in [onDown],
17+
* and call [PointerInputChange.consumePositionChange]
18+
* in [onMove] block.
19+
*
20+
* @param onDown is invoked when first pointer is down initially.
21+
* @param onMove one or multiple pointers are being moved on screen.
22+
* @param onUp last pointer is up
23+
* @param delayAfterDownInMillis is optional delay after [onDown] This delay might be
24+
* required Composables like **Canvas** to process [onDown] before [onMove]
25+
*
26+
27+
*/
28+
suspend fun PointerInputScope.detectMotionEvents(
29+
onDown: (PointerInputChange) -> Unit = {},
30+
onMove: (PointerInputChange) -> Unit = {},
31+
onUp: (PointerInputChange) -> Unit = {},
32+
delayAfterDownInMillis: Long = 0L,
33+
) {
34+
coroutineScope {
35+
awaitEachGesture {
36+
// Wait for at least one pointer to press down, and set first contact position
37+
val down: PointerInputChange = awaitFirstDown()
38+
onDown(down)
39+
40+
var pointer = down
41+
// Main pointer is the one that is down initially
42+
var pointerId = down.id
43+
44+
// If a move event is followed fast enough down is skipped, especially by Canvas
45+
// to prevent it we add delay after first touch
46+
var waitedAfterDown = false
47+
48+
launch {
49+
delay(delayAfterDownInMillis)
50+
waitedAfterDown = true
51+
}
52+
53+
while (true) {
54+
55+
val event: PointerEvent = awaitPointerEvent()
56+
57+
val anyPressed = event.changes.any { it.pressed }
58+
59+
// There are at least one pointer pressed
60+
if (anyPressed) {
61+
// Get pointer that is down, if first pointer is up
62+
// get another and use it if other pointers are also down
63+
// event.changes.first() doesn't return same order
64+
val pointerInputChange =
65+
event.changes.firstOrNull { it.id == pointerId }
66+
?: event.changes.first()
67+
68+
// Next time will check same pointer with this id
69+
pointerId = pointerInputChange.id
70+
pointer = pointerInputChange
71+
72+
if (waitedAfterDown) {
73+
onMove(pointer)
74+
}
75+
} else {
76+
// All of the pointers are up
77+
onUp(pointer)
78+
break
79+
}
80+
}
81+
}
82+
}
83+
}
84+
85+
/**
86+
* Reads [awaitFirstDown], and [awaitPointerEvent] to
87+
* get [PointerInputChange] and motion event states
88+
* [onDown], [onMove], and [onUp]. Unlike overload of this function [onMove] returns
89+
* list of [PointerInputChange] to get data about all pointers that are on the screen.
90+
*
91+
* To prevent other pointer functions that call [awaitFirstDown] or [awaitPointerEvent]
92+
* (scroll, swipe, detect functions)
93+
* receiving changes call [PointerInputChange.consume] in [onDown],
94+
* and call [PointerInputChange.consumePositionChange]
95+
* in [onMove] block.
96+
*
97+
* @param onDown is invoked when first pointer is down initially.
98+
* @param onMove one or multiple pointers are being moved on screen.
99+
* @param onUp last pointer is up
100+
* @param delayAfterDownInMillis is optional delay after [onDown] This delay might be
101+
* required Composables like **Canvas** to process [onDown] before [onMove]
102+
*
103+
*/
104+
suspend fun PointerInputScope.detectMotionEventsAsList(
105+
onDown: (PointerInputChange) -> Unit = {},
106+
onMove: (List<PointerInputChange>) -> Unit = {},
107+
onUp: (PointerInputChange) -> Unit = {},
108+
delayAfterDownInMillis: Long = 0L,
109+
) {
110+
111+
coroutineScope {
112+
awaitEachGesture {
113+
// Wait for at least one pointer to press down, and set first contact position
114+
val down: PointerInputChange = awaitFirstDown()
115+
onDown(down)
116+
117+
var pointer = down
118+
// Main pointer is the one that is down initially
119+
var pointerId = down.id
120+
121+
// If a move event is followed fast enough down is skipped, especially by Canvas
122+
// to prevent it we add delay after first touch
123+
var waitedAfterDown = false
124+
125+
launch {
126+
delay(delayAfterDownInMillis)
127+
waitedAfterDown = true
128+
}
129+
130+
while (true) {
131+
132+
val event: PointerEvent = awaitPointerEvent()
133+
134+
val anyPressed = event.changes.any { it.pressed }
135+
136+
// There are at least one pointer pressed
137+
if (anyPressed) {
138+
// Get pointer that is down, if first pointer is up
139+
// get another and use it if other pointers are also down
140+
// event.changes.first() doesn't return same order
141+
val pointerInputChange =
142+
event.changes.firstOrNull { it.id == pointerId }
143+
?: event.changes.first()
144+
145+
// Next time will check same pointer with this id
146+
pointerId = pointerInputChange.id
147+
pointer = pointerInputChange
148+
149+
if (waitedAfterDown) {
150+
onMove(event.changes)
151+
}
152+
153+
} else {
154+
// All of the pointers are up
155+
onUp(pointer)
156+
break
157+
}
158+
}
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)