Updated on 2026-08-14
This commit is contained in:
parent
7658f822c1
commit
5293a5021f
2 changed files with 61 additions and 30 deletions
|
|
@ -1,45 +1,68 @@
|
|||
package com.tangem.tap.features.home.compose
|
||||
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.material.LocalTextStyle
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.drawWithContent
|
||||
import androidx.compose.ui.text.TextLayoutResult
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.ExperimentalUnitApi
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
@OptIn(ExperimentalUnitApi::class)
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
@Composable
|
||||
fun AutoSizeText(
|
||||
fun TextAutoSize(
|
||||
modifier: Modifier = Modifier,
|
||||
text: String,
|
||||
textStyle: TextStyle,
|
||||
modifier: Modifier = Modifier
|
||||
textStyle: TextStyle = LocalTextStyle.current,
|
||||
fontSizeRange: FontSizeRange,
|
||||
) {
|
||||
val scaledTextStyle = remember { mutableStateOf(textStyle) }
|
||||
val fontSizeValue = remember { mutableStateOf(fontSizeRange.max.value) }
|
||||
val readyToDraw = remember { mutableStateOf(false) }
|
||||
|
||||
val onTextLayout: (TextLayoutResult) -> Unit = { result ->
|
||||
if (result.didOverflowWidth) {
|
||||
val fontSize = result.size.width / result.multiParagraph.width
|
||||
scaledTextStyle.value =
|
||||
// scaledTextStyle.value.copy(fontSize = TextUnit(fontSize, TextUnitType.Sp))
|
||||
scaledTextStyle.value.copy(fontSize = scaledTextStyle.value.fontSize * 0.9)
|
||||
} else {
|
||||
readyToDraw.value = true
|
||||
}
|
||||
val textState = remember { mutableStateOf(text) }
|
||||
if (textState.value != text) {
|
||||
readyToDraw.value = false
|
||||
fontSizeValue.value = fontSizeRange.max.value
|
||||
textState.value = text
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = modifier.drawWithContent { if (readyToDraw.value) drawContent() },
|
||||
text = text,
|
||||
modifier = modifier.drawWithContent {
|
||||
if (readyToDraw.value) {
|
||||
drawContent()
|
||||
}
|
||||
},
|
||||
softWrap = false,
|
||||
onTextLayout = onTextLayout,
|
||||
style = scaledTextStyle.value,
|
||||
)
|
||||
style = textStyle,
|
||||
fontSize = fontSizeValue.value.sp,
|
||||
onTextLayout = {
|
||||
if (it.hasVisualOverflow) {
|
||||
val nextFontSizeValue = fontSizeValue.value - fontSizeRange.step.value
|
||||
if (nextFontSizeValue <= fontSizeRange.min.value) {
|
||||
fontSizeValue.value = fontSizeRange.min.value
|
||||
readyToDraw.value = true
|
||||
} else {
|
||||
fontSizeValue.value = nextFontSizeValue * 0.8f
|
||||
}
|
||||
} else {
|
||||
readyToDraw.value = true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
data class FontSizeRange(
|
||||
val min: TextUnit,
|
||||
val max: TextUnit,
|
||||
val step: TextUnit = DEFAULT_TEXT_STEP,
|
||||
) {
|
||||
init {
|
||||
require(min < max) { "min should be less than max, $this" }
|
||||
require(step.value > 0) { "step should be greater than 0, $this" }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_TEXT_STEP = 1.sp
|
||||
}
|
||||
}
|
||||
|
|
@ -96,25 +96,33 @@ fun FirstStoriesContent(
|
|||
)
|
||||
|
||||
if (screenState.value != StartingScreenState.MEET_TANGEM) {
|
||||
AutoSizeText(text = text?.let { stringResource(text) } ?: "", textStyle = style,
|
||||
TextAutoSize(
|
||||
modifier = Modifier
|
||||
.padding(start = 40.dp, end = 40.dp)
|
||||
.alpha(if (screenState.value == StartingScreenState.SHOW_CARD) 0f else 1f),)
|
||||
.padding(start = 40.dp, end = 40.dp, bottom = 100.dp)
|
||||
.alpha(if (screenState.value == StartingScreenState.SHOW_CARD) 0f else 1f),
|
||||
text = text?.let { stringResource(text) } ?: "",
|
||||
textStyle = style,
|
||||
fontSizeRange = FontSizeRange(40.sp, 60.sp)
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = screenState.value == StartingScreenState.MEET_TANGEM,
|
||||
enter = slideInVertically() { it / 2 }
|
||||
) {
|
||||
AutoSizeText(text = text?.let { stringResource(text) } ?: "", textStyle = style,
|
||||
TextAutoSize(
|
||||
modifier = Modifier
|
||||
.padding(start = 40.dp, end = 40.dp)
|
||||
.fillMaxWidth()
|
||||
.padding(start = 40.dp, end = 40.dp),
|
||||
text = text?.let { stringResource(text) } ?: "",
|
||||
textStyle = style,
|
||||
fontSizeRange = FontSizeRange(20.sp, 60.sp)
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = screenState.value == StartingScreenState.SHOW_CARD ||
|
||||
screenState.value == StartingScreenState.MEET_TANGEM,
|
||||
screenState.value == StartingScreenState.MEET_TANGEM,
|
||||
enter = scaleIn(initialScale = 3f)
|
||||
) {
|
||||
Image(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue