@@ -6,14 +6,13 @@ import androidx.compose.animation.core.animateDpAsState
66import androidx.compose.animation.core.spring
77import androidx.compose.animation.core.tween
88import androidx.compose.foundation.background
9- import androidx.compose.foundation.gestures.Orientation
109import androidx.compose.foundation.gestures.awaitEachGesture
1110import androidx.compose.foundation.gestures.awaitFirstDown
1211import androidx.compose.foundation.gestures.awaitVerticalTouchSlopOrCancellation
13- import androidx.compose.foundation.gestures.draggable
14- import androidx.compose.foundation.gestures.rememberDraggableState
12+ import androidx.compose.foundation.gestures.detectHorizontalDragGestures
1513import androidx.compose.foundation.gestures.waitForUpOrCancellation
1614import androidx.compose.foundation.hoverable
15+ import androidx.compose.foundation.interaction.DragInteraction
1716import androidx.compose.foundation.interaction.MutableInteractionSource
1817import androidx.compose.foundation.interaction.PressInteraction
1918import androidx.compose.foundation.interaction.collectIsDraggedAsState
@@ -188,10 +187,34 @@ fun Switch(
188187 }
189188 }
190189 }
191- .draggable(
192- state = rememberDraggableState { delta ->
193- if (onCheckedChange == null ) return @rememberDraggableState
194- dragOffset = (dragOffset + delta / 2 ).let {
190+ .pointerInput(Unit ) {
191+ if (! enabled) return @pointerInput
192+ val dragInteraction: DragInteraction .Start = DragInteraction .Start ()
193+ detectHorizontalDragGestures(
194+ onDragStart = {
195+ interactionSource.tryEmit(dragInteraction)
196+ hasVibrated = false
197+ },
198+ onDragEnd = {
199+ if (dragOffset.absoluteValue > 21f / 2 ) onCheckedChange?.invoke(! isChecked)
200+ if (! hasVibratedOnce && dragOffset.absoluteValue >= 1f ) {
201+ if ((isChecked && dragOffset <= - 11f ) || (! isChecked && dragOffset <= 10f )) {
202+ hapticFeedback.performHapticFeedback(HapticFeedbackType .ToggleOff )
203+ } else if ((isChecked && dragOffset >= - 10f ) || (! isChecked && dragOffset >= 11f )) {
204+ hapticFeedback.performHapticFeedback(HapticFeedbackType .ToggleOn )
205+ }
206+ }
207+ interactionSource.tryEmit(DragInteraction .Stop (dragInteraction))
208+ hasVibrated = true
209+ hasVibratedOnce = false
210+ dragOffset = 0f
211+ },
212+ onDragCancel = {
213+ interactionSource.tryEmit(DragInteraction .Cancel (dragInteraction))
214+ dragOffset = 0f
215+ }
216+ ) { _, dragAmount ->
217+ dragOffset = (dragOffset + dragAmount / 2 ).let {
195218 if (isChecked) it.coerceIn(- 21f , 0f ) else it.coerceIn(0f , 21f )
196219 }
197220 if (dragOffset in - 11f .. - 10f || dragOffset in 10f .. 11f ) {
@@ -209,24 +232,8 @@ fun Switch(
209232 hasVibratedOnce = true
210233 }
211234 }
212- },
213- orientation = Orientation .Horizontal ,
214- enabled = enabled,
215- interactionSource = interactionSource,
216- onDragStopped = {
217- if (dragOffset.absoluteValue > 21f / 2 ) onCheckedChange?.invoke(! isChecked)
218- if (! hasVibratedOnce && dragOffset.absoluteValue >= 1f ) {
219- if ((isChecked && dragOffset <= - 11f ) || (! isChecked && dragOffset <= 10f )) {
220- hapticFeedback.performHapticFeedback(HapticFeedbackType .ToggleOff )
221- } else if ((isChecked && dragOffset >= - 10f ) || (! isChecked && dragOffset >= 11f )) {
222- hapticFeedback.performHapticFeedback(HapticFeedbackType .ToggleOn )
223- }
224- }
225- hasVibrated = true
226- hasVibratedOnce = false
227- dragOffset = 0f
228235 }
229- )
236+ }
230237 )
231238 }
232239}
0 commit comments