I am loading text dynamically from a list of objects that contain varying text from one object to another. Some text values are short enough to fit in the Text view, while others are too long. So the idea is to have the long text values start auto-scrolling to the left, at a human-readable pace, that is after a wait of 500L milliseconds, revealing the elipsized/ hidden text until the last character, then stopping until the next text update, which, if it is longer than the Text view, must start at the initial position and scroll after 500L milliseconds, otherwise remain stationarily contained if it is short text.
I have tried a number of ways to manipulate the code, but to no avail. Here is a sample of the code I am working with, in which the text is Scrollable but only happening manually by dragging. I want it to auto-scroll after 500L milliseconds delay from update time:
Column(
modifier = Modifier
.height(25.dp)
.fillMaxSize()
.background(color = slideCaptionBg, shape = RoundedCornerShape(16.dp))
.clickable { columnClicked.value = true },
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
val textState = remember { Animatable(0f) }
val scrollState = rememberScrollState()
LaunchedEffect(Unit) {
while (true) {
val targetValue = if (textWidth < 800) (textWidth - 800).toFloat() else 0F
textState.animateTo(targetValue, animationSpec = tween(800))
delay(500L)
textState.animateTo(0F, animationSpec = tween(800))
delay(4000L)
}
}
Row(
modifier = Modifier
.fillMaxSize()
.padding(end = 8.dp, start = 8.dp)
.width(IntrinsicSize.Min)
.horizontalScroll(scrollState)
.background(Color.Transparent),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(
R.string.song_art_slide_caption, // %s by %s <-- This is the string resource with variable spaces.
newArtSlide.track,
newArtSlide.artist
),
modifier = Modifier
.background(Color.Transparent),
color = Color.White,
fontSize = 16.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
softWrap = false,
style = MaterialTheme.typography.titleMedium,
textAlign = TextAlign.Center,
)
}
if (columnClicked.value) {
UtilFunctions.showSnackBar(
coroutineScope = coroutineScope,
snackState = snackState,
message = "Show Song If Signed in!"
)
columnClicked.value = false
}
}
please take a look at the basicMarquee modifier. e.g.
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
val focusRequester = remember { FocusRequester() }
Text(
modifier = Modifier
.basicMarquee(animationMode = MarqueeAnimationMode.WhileFocused)
.focusRequester(focusRequester)
.focusable()
.clickable { focusRequester.requestFocus() },
text = "Compose has finally added support for Marquee! It's soo easy to implement!"
)
}
You could simulate an auto-scroll effect by animating a Modifier.offset. Here's an example:
val infiniteTransition = rememberInfiniteTransition()
val scroll by infiniteTransition.animateFloat(
initialValue = 1f,
targetValue = 0f,
animationSpec = infiniteRepeatable(
animation = tween(5000, easing = LinearEasing),
repeatMode = RepeatMode.Restart
)
)
Text(
"Your long text goes here...",
modifier = Modifier
.offset(x = Dp(500 * scroll))
.padding(16.dp),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
In this code, animateFloat from an InfiniteTransition is used to animate a float value from 1f to 0f. This value is then used in an offset modifier for the Text composable, which moves it horizontally.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With