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