@@ -24,7 +24,6 @@ import androidx.compose.runtime.setValue
2424import androidx.compose.ui.Alignment
2525import androidx.compose.ui.Modifier
2626import androidx.compose.ui.draw.clip
27- import androidx.compose.ui.draw.drawBehind
2827import androidx.compose.ui.graphics.Color
2928import androidx.compose.ui.hapticfeedback.HapticFeedbackType
3029import androidx.compose.ui.input.pointer.pointerInput
@@ -33,7 +32,6 @@ import androidx.compose.ui.semantics.Role
3332import androidx.compose.ui.unit.Dp
3433import androidx.compose.ui.unit.dp
3534import top.yukonga.miuix.kmp.theme.MiuixTheme
36- import top.yukonga.miuix.kmp.utils.SmoothRoundedCornerShape
3735import kotlin.math.absoluteValue
3836
3937/* *
@@ -63,13 +61,14 @@ fun Switch(
6361 )
6462 }
6563 var isPressed by remember { mutableStateOf(false ) }
66- var dragOffset by remember { mutableStateOf(0f ) }
64+ var trackDragOffset by remember { mutableStateOf(0f ) }
65+ var thumbDragOffset by remember { mutableStateOf(0f ) }
6766 val thumbOffset by animateDpAsState(
6867 targetValue = if (isChecked) {
69- if (! enabled) 28 .dp else if (isPressed) 26.5 . dp else 28 .dp
68+ if (! enabled) 26 .dp else if (isPressed) 24 . dp else 26 .dp
7069 } else {
71- if (! enabled) 4 .dp else if (isPressed) 2.5 .dp else 4 .dp
72- } + dragOffset .dp,
70+ if (! enabled) 4 .dp else if (isPressed) 3 .dp else 4 .dp
71+ } + thumbDragOffset .dp,
7372 animationSpec = springSpec
7473 )
7574
@@ -108,63 +107,81 @@ fun Switch(
108107 Box (
109108 modifier = modifier
110109 .wrapContentSize(Alignment .Center )
111- .size(52 .dp, 28.5 .dp)
112- .requiredSize(52 .dp, 28.5 .dp)
113- .clip(SmoothRoundedCornerShape ( 52 .dp))
114- .drawBehind { drawRect (backgroundColor) }
110+ .size(50 .dp, 28.5 .dp)
111+ .requiredSize(50 .dp, 28.5 .dp)
112+ .clip(RoundedCornerShape ( 100 .dp))
113+ .background (backgroundColor)
115114 .pointerInput(Unit ) {
116115 detectHorizontalDragGestures(
117- onDragStart = {
118- isPressed = true
119- hasVibrated = false
120- },
121116 onDragEnd = {
122- isPressed = false
123- val switchWidth = 24f
124- if (dragOffset.absoluteValue > switchWidth / 2 ) {
125- if (enabled) onCheckedChange?.invoke( ! isChecked )
117+ if (trackDragOffset != 0f ) {
118+ onCheckedChange?.invoke( ! isChecked)
119+ if (thumbOffset == 4 .dp || thumbOffset == 26 .dp)
120+ hapticFeedback.performHapticFeedback( HapticFeedbackType . LongPress )
126121 }
127- dragOffset = 0f
122+ trackDragOffset = 0f
128123 },
129124 onDragCancel = {
130- isPressed = false
131- dragOffset = 0f
132- },
133- onHorizontalDrag = { change, dragAmount ->
125+ trackDragOffset = 0f
126+ }
127+ ) { change, dragAmount ->
128+ if (! enabled) return @detectHorizontalDragGestures
129+ trackDragOffset = dragAmount
130+ change.consume()
131+ }
132+ }
133+ .then(toggleableModifier)
134+ ) {
135+ Box (
136+ modifier = Modifier
137+ .padding(start = thumbOffset)
138+ .align(Alignment .CenterStart )
139+ .size(thumbSize)
140+ .background(
141+ color = thumbColor,
142+ shape = RoundedCornerShape (100 .dp)
143+ )
144+ .pointerInput(Unit ) {
145+ detectHorizontalDragGestures(
146+ onDragStart = {
147+ isPressed = true
148+ hasVibrated = false
149+ },
150+ onDragEnd = {
151+ isPressed = false
152+ val switchWidth = 21f
153+ if (thumbDragOffset.absoluteValue > switchWidth / 2 ) {
154+ onCheckedChange?.invoke(! isChecked)
155+ }
156+ thumbDragOffset = 0f
157+ },
158+ onDragCancel = {
159+ isPressed = false
160+ thumbDragOffset = 0f
161+ }
162+ ) { change, dragAmount ->
134163 if (! enabled) return @detectHorizontalDragGestures
135- val newOffset = dragOffset + dragAmount / 2
136- dragOffset =
137- if (isChecked) newOffset.coerceIn(- 24f , 0f ) else newOffset.coerceIn(0f , 24f )
164+ val newOffset = thumbDragOffset + dragAmount / 2
165+ thumbDragOffset =
166+ if (isChecked) newOffset.coerceIn(- 21f , 0f ) else newOffset.coerceIn(0f , 21f )
138167 if (isChecked) {
139- if (dragOffset in - 23f .. - 1f ) {
168+ if (thumbDragOffset in - 20f .. - 1f ) {
140169 hasVibrated = false
141- } else if ((dragOffset == - 24f || dragOffset == 0f ) && ! hasVibrated) {
170+ } else if ((thumbDragOffset == - 21f || thumbDragOffset == 0f ) && ! hasVibrated) {
142171 hapticFeedback.performHapticFeedback(HapticFeedbackType .LongPress )
143172 hasVibrated = true
144173 }
145174 } else {
146- if (dragOffset in 1f .. 23f ) {
175+ if (thumbDragOffset in 1f .. 20f ) {
147176 hasVibrated = false
148- } else if ((dragOffset == 0f || dragOffset == 24f ) && ! hasVibrated) {
177+ } else if ((thumbDragOffset == 0f || thumbDragOffset == 21f ) && ! hasVibrated) {
149178 hapticFeedback.performHapticFeedback(HapticFeedbackType .LongPress )
150179 hasVibrated = true
151180 }
152181 }
153182 change.consume()
154183 }
155- )
156- }
157- .then(toggleableModifier)
158- ) {
159- Box (
160- modifier = Modifier
161- .padding(start = thumbOffset)
162- .align(Alignment .CenterStart )
163- .size(thumbSize)
164- .background(
165- color = thumbColor,
166- shape = RoundedCornerShape (100 .dp)
167- )
184+ }
168185 )
169186 }
170187}
@@ -210,14 +227,18 @@ class SwitchColors(
210227 private val disabledUncheckedTrackColor : Color
211228) {
212229 @Stable
213- internal fun checkedThumbColor (enabled : Boolean ): Color = if (enabled) checkedThumbColor else disabledCheckedThumbColor
230+ internal fun checkedThumbColor (enabled : Boolean ): Color =
231+ if (enabled) checkedThumbColor else disabledCheckedThumbColor
214232
215233 @Stable
216- internal fun uncheckedThumbColor (enabled : Boolean ): Color = if (enabled) uncheckedThumbColor else disabledUncheckedThumbColor
234+ internal fun uncheckedThumbColor (enabled : Boolean ): Color =
235+ if (enabled) uncheckedThumbColor else disabledUncheckedThumbColor
217236
218237 @Stable
219- internal fun checkedTrackColor (enabled : Boolean ): Color = if (enabled) checkedTrackColor else disabledCheckedTrackColor
238+ internal fun checkedTrackColor (enabled : Boolean ): Color =
239+ if (enabled) checkedTrackColor else disabledCheckedTrackColor
220240
221241 @Stable
222- internal fun uncheckedTrackColor (enabled : Boolean ): Color = if (enabled) uncheckedTrackColor else disabledUncheckedTrackColor
242+ internal fun uncheckedTrackColor (enabled : Boolean ): Color =
243+ if (enabled) uncheckedTrackColor else disabledUncheckedTrackColor
223244}
0 commit comments