ChapterNavigator use RollingNumber, no dynamic size
This commit is contained in:
1 parent
baf8333b70
commit
39398365e5
2 files changed
+74
-66
No files matched your search
@@ -6,7 +6,6 @@ import androidx.compose.foundation.interaction.collectIsDraggedAsState
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -20,6 +19,8 @@ import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.ehviewer.core.ui.component.IntSliderState
|
||||
import com.ehviewer.core.ui.component.RollingNumber
|
||||
import com.ehviewer.core.ui.component.RollingNumberPlaceholder
|
||||
import com.ehviewer.core.ui.component.Slider
|
||||
import com.ehviewer.core.ui.component.defaultMaxTickCount
|
||||
import com.ehviewer.core.ui.util.HapticFeedbackType
|
||||
@@ -41,7 +42,7 @@ fun ChapterNavigator(
|
||||
modifier = Modifier.padding(horizontal = horizontalPadding).clip(CircleShape).background(containerColor).padding(horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(text = "${slider.value}")
|
||||
RollingNumber(slider.value, length = "$totalPages".length)
|
||||
val maxTickCount = defaultMaxTickCount()
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
if (slider.state.steps < maxTickCount) {
|
||||
@@ -60,6 +61,6 @@ fun ChapterNavigator(
|
||||
maxTickCount = maxTickCount,
|
||||
interactionSource = interactionSource,
|
||||
)
|
||||
Text(text = "$totalPages")
|
||||
RollingNumberPlaceholder(totalPages)
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -23,11 +24,13 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.takeOrElse
|
||||
import androidx.compose.ui.layout.layout
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.rememberTextMeasurer
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.toSize
|
||||
import kotlin.math.PI
|
||||
@@ -55,14 +58,16 @@ fun rememberTextStyleNumberMaxSize(textStyle: TextStyle): DpSize {
|
||||
fun RollingNumberPlaceholder(number: Int, style: TextStyle = LocalTextStyle.current) {
|
||||
val styleNoSpacing = style.copy(letterSpacing = TextUnit.Unspecified)
|
||||
val size = rememberTextStyleNumberMaxSize(style)
|
||||
Row(horizontalArrangement = Arrangement.Center) {
|
||||
"$number".forEach { char ->
|
||||
Text(
|
||||
text = "$char",
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.size(size),
|
||||
)
|
||||
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
|
||||
Row(horizontalArrangement = Arrangement.Center) {
|
||||
"$number".forEach { char ->
|
||||
Text(
|
||||
text = "$char",
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.size(size),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,69 +143,71 @@ fun RollingNumber(
|
||||
val transition = updateTransition(string)
|
||||
val styleNoSpacing = style.merge(color = textColor).copy(letterSpacing = TextUnit.Unspecified)
|
||||
val size = rememberTextStyleNumberMaxSize(style)
|
||||
LazyRow(
|
||||
modifier = modifier.clipToBounds().layout { measurable, constraints ->
|
||||
val placeable = measurable.measure(constraints.copy(maxHeight = Int.MAX_VALUE))
|
||||
layout(width = placeable.width, height = size.height.roundToPx()) {
|
||||
placeable.place(0, 0)
|
||||
}
|
||||
},
|
||||
reverseLayout = true,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
val max = with(transition) { max(currentState.length, targetState.length) }
|
||||
items(max, key = { it }) { reversed ->
|
||||
val rotate by transition.animateOffset { str ->
|
||||
val len = str.length
|
||||
val absent = max - len
|
||||
val where = max - reversed - 1
|
||||
val v = if (where < absent) null else str[where - absent].digitToInt()
|
||||
conceptSpaceToIntermediate(v)
|
||||
}
|
||||
if (reversed != 0 && reversed % 3 == 0 && separator) {
|
||||
Text(
|
||||
text = ",",
|
||||
modifier = Modifier.size(size),
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.animateItem().offset {
|
||||
val number = intermediateToNumberOffset(rotate)
|
||||
numberOffsetToUIOffset(size.height.roundToPx(), number)
|
||||
},
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
repeat(10) { i ->
|
||||
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
|
||||
LazyRow(
|
||||
modifier = modifier.clipToBounds().layout { measurable, constraints ->
|
||||
val placeable = measurable.measure(constraints.copy(maxHeight = Int.MAX_VALUE))
|
||||
layout(width = placeable.width, height = size.height.roundToPx()) {
|
||||
placeable.place(0, 0)
|
||||
}
|
||||
},
|
||||
reverseLayout = true,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
val max = with(transition) { max(currentState.length, targetState.length) }
|
||||
items(max, key = { it }) { reversed ->
|
||||
val rotate by transition.animateOffset { str ->
|
||||
val len = str.length
|
||||
val absent = max - len
|
||||
val where = max - reversed - 1
|
||||
val v = if (where < absent) null else str[where - absent].digitToInt()
|
||||
conceptSpaceToIntermediate(v)
|
||||
}
|
||||
if (reversed != 0 && reversed % 3 == 0 && separator) {
|
||||
Text(
|
||||
text = "$i",
|
||||
modifier = Modifier.size(size),
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
Text(
|
||||
text = "",
|
||||
text = ",",
|
||||
modifier = Modifier.size(size),
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.animateItem().offset {
|
||||
val number = intermediateToNumberOffset(rotate)
|
||||
numberOffsetToUIOffset(size.height.roundToPx(), number)
|
||||
},
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
repeat(10) { i ->
|
||||
Text(
|
||||
text = "$i",
|
||||
modifier = Modifier.size(size),
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
Text(
|
||||
text = "",
|
||||
modifier = Modifier.size(size),
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isNegative) {
|
||||
item(key = -1) {
|
||||
Text(
|
||||
text = "-",
|
||||
modifier = Modifier.size(size).animateItem(),
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
if (isNegative) {
|
||||
item(key = -1) {
|
||||
Text(
|
||||
text = "-",
|
||||
modifier = Modifier.size(size).animateItem(),
|
||||
style = styleNoSpacing,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (length != null) {
|
||||
items(length - max - if (isNegative) 1 else 0) {
|
||||
Spacer(Modifier.size(size))
|
||||
if (length != null) {
|
||||
items(length - max - if (isNegative) 1 else 0) {
|
||||
Spacer(Modifier.size(size))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user