Skip to content

Commit cb10180

Browse files
authored
library: Refactor PressFeedback to use Modifier.Node (#99)
* library: Refactor PressFeedback to use Modifier.Node
1 parent 2909ec2 commit cb10180

File tree

6 files changed

+257
-132
lines changed

6 files changed

+257
-132
lines changed

docs/guide/utils.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,18 @@ Box(
193193
)
194194
```
195195

196+
If you want to use both `Modifier.clickable()` and instant feedback, you can pass the `immediate = true` parameter.
197+
198+
```kotlin
199+
val interactionSource = remember { MutableInteractionSource() }
200+
201+
Box(
202+
modifier = Modifier
203+
.clickable(interactionSource = interactionSource, indication = null, onClick = {})
204+
.pressSink(interactionSource, immediate = true)
205+
)
206+
```
207+
196208
### Press Feedback Type (`PressFeedbackType`)
197209

198210
The `PressFeedbackType` enum defines different types of visual feedback that can be applied when the component is pressed.

docs/zh_CN/guide/utils.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,18 @@ Box(
193193
)
194194
```
195195

196+
如果既想使用 `Modifier.clickable()` 又想要即时的反馈效果,可以传递 `immediate = true` 参数。
197+
198+
```kotlin
199+
val interactionSource = remember { MutableInteractionSource() }
200+
201+
Box(
202+
modifier = Modifier
203+
.clickable(interactionSource = interactionSource, indication = null, onClick = {})
204+
.pressSink(interactionSource, immediate = true)
205+
)
206+
```
207+
196208
### 按压反馈类型 (PressFeedbackType)
197209

198210
`PressFeedbackType` 枚举定义了组件被按下时可以应用的不同类型的视觉反馈。

example/src/commonMain/kotlin/component/OtherComponent.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ import androidx.compose.ui.focus.FocusManager
3232
import androidx.compose.ui.graphics.Color
3333
import androidx.compose.ui.graphics.toArgb
3434
import androidx.compose.ui.graphics.vector.ImageVector
35-
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
36-
import androidx.compose.ui.platform.LocalHapticFeedback
3735
import androidx.compose.ui.text.font.FontWeight
3836
import androidx.compose.ui.text.input.ImeAction
3937
import androidx.compose.ui.text.input.TextFieldValue
@@ -481,8 +479,7 @@ fun LazyListScope.otherComponent(
481479
),
482480
insideMargin = PaddingValues(16.dp),
483481
pressFeedbackType = PressFeedbackType.None,
484-
showIndication = true,
485-
onClick = { }
482+
showIndication = true
486483
) {
487484
Text(
488485
color = MiuixTheme.colorScheme.onPrimary,
@@ -497,7 +494,6 @@ fun LazyListScope.otherComponent(
497494
fontWeight = FontWeight.Normal
498495
)
499496
}
500-
val hapticFeedback = LocalHapticFeedback.current
501497
Row(
502498
modifier = Modifier
503499
.fillMaxWidth()
@@ -510,7 +506,7 @@ fun LazyListScope.otherComponent(
510506
insideMargin = PaddingValues(16.dp),
511507
pressFeedbackType = PressFeedbackType.Sink,
512508
showIndication = true,
513-
onClick = { },
509+
onClick = { println("Card click") },
514510
content = {
515511
Text(
516512
color = MiuixTheme.colorScheme.onSurface,
@@ -529,7 +525,7 @@ fun LazyListScope.otherComponent(
529525
modifier = Modifier.weight(1f),
530526
insideMargin = PaddingValues(16.dp),
531527
pressFeedbackType = PressFeedbackType.Tilt,
532-
onLongPress = { hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) },
528+
onLongPress = { println("Card long press") },
533529
content = {
534530
Text(
535531
color = MiuixTheme.colorScheme.onSurface,

iosApp/iosApp/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundleShortVersionString</key>
1818
<string>1.0.4</string>
1919
<key>CFBundleVersion</key>
20-
<string>515</string>
20+
<string>517</string>
2121
<key>LSRequiresIPhoneOS</key>
2222
<true/>
2323
<key>CADisableMinimumFrameDurationOnPhone</key>

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Card.kt

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,8 @@ package top.yukonga.miuix.kmp.basic
55

66
import androidx.compose.foundation.LocalIndication
77
import androidx.compose.foundation.background
8-
import androidx.compose.foundation.gestures.awaitEachGesture
9-
import androidx.compose.foundation.gestures.awaitFirstDown
10-
import androidx.compose.foundation.gestures.detectTapGestures
11-
import androidx.compose.foundation.gestures.waitForUpOrCancellation
12-
import androidx.compose.foundation.hoverable
13-
import androidx.compose.foundation.indication
8+
import androidx.compose.foundation.combinedClickable
149
import androidx.compose.foundation.interaction.MutableInteractionSource
15-
import androidx.compose.foundation.interaction.PressInteraction
1610
import androidx.compose.foundation.layout.Box
1711
import androidx.compose.foundation.layout.Column
1812
import androidx.compose.foundation.layout.ColumnScope
@@ -26,7 +20,6 @@ import androidx.compose.ui.Modifier
2620
import androidx.compose.ui.draw.clip
2721
import androidx.compose.ui.graphics.Color
2822
import androidx.compose.ui.graphics.takeOrElse
29-
import androidx.compose.ui.input.pointer.pointerInput
3023
import androidx.compose.ui.semantics.isTraversalGroup
3124
import androidx.compose.ui.semantics.semantics
3225
import androidx.compose.ui.unit.Dp
@@ -104,43 +97,23 @@ fun Card(
10497
val pressFeedbackModifier = remember(pressFeedbackType, interactionSource) {
10598
when (pressFeedbackType) {
10699
PressFeedbackType.None -> Modifier
107-
PressFeedbackType.Sink -> Modifier.pressSink(interactionSource)
108-
PressFeedbackType.Tilt -> Modifier.pressTilt(interactionSource)
100+
PressFeedbackType.Sink -> Modifier.pressSink(interactionSource, immediate = true)
101+
PressFeedbackType.Tilt -> Modifier.pressTilt(interactionSource, immediate = true)
109102
}
110103
}
111104

112105
BasicCard(
113-
modifier = modifier
114-
.pointerInput(onClick, onLongPress) {
115-
detectTapGestures(
116-
onTap = { onClick?.invoke() },
117-
onLongPress = { onLongPress?.invoke() }
118-
)
119-
}
120-
.pointerInput(interactionSource) {
121-
awaitEachGesture {
122-
val pressInteraction: PressInteraction.Press
123-
awaitFirstDown().also {
124-
pressInteraction = PressInteraction.Press(it.position)
125-
interactionSource.tryEmit(pressInteraction)
126-
}
127-
if (waitForUpOrCancellation() == null) {
128-
interactionSource.tryEmit(PressInteraction.Cancel(pressInteraction))
129-
} else {
130-
interactionSource.tryEmit(PressInteraction.Release(pressInteraction))
131-
}
132-
}
133-
}
134-
.hoverable(interactionSource)
135-
.then(pressFeedbackModifier),
106+
modifier = modifier.then(pressFeedbackModifier),
136107
cornerRadius = cornerRadius,
137108
colors = colors
138109
) {
139110
Column(
140111
modifier = Modifier
141-
.indication(
112+
.combinedClickable(
142113
interactionSource = interactionSource,
143-
indication = if (showIndication == true) LocalIndication.current else null
114+
indication = if (showIndication == true) LocalIndication.current else null,
115+
onClick = { onClick?.invoke() },
116+
onLongClick = onLongPress
144117
)
145118
.padding(insideMargin),
146119
content = content

0 commit comments

Comments
 (0)