Jetpack Compose中如何实现Marquee文本跑马灯滚动效果?
Jetpack Compose 实现文本跑马灯效果方案
方案1:官方原生实现(Compose 1.4.0 及以上推荐)
Compose 从1.4.0-alpha04版本开始内置了跑马灯支持,仅需给Text组件添加basicMarquee修饰符即可实现:
// 需导入compose.foundation的basicMarquee扩展 import androidx.compose.foundation.basicMarquee Text( text = "超长文本超长文本超长文本超长文本超长文本超长文本", modifier = Modifier .fillMaxWidth() .basicMarquee( iterations = Int.MAX_VALUE, // 无限滚动 animationMode = MarqueeAnimationMode.WhileVisible, // 可见时自动滚动 delayMillis = 1000, // 滚动前停留1秒 velocity = 30.dp // 滚动速度为每秒30dp ), maxLines = 1 )
常用参数说明:
iterations:滚动重复次数,设置为Int.MAX_VALUE即可实现无限滚动animationMode:滚动触发条件,可选WhileFocused(获得焦点时滚动)、WhileVisible(组件可见时滚动)、Always(始终滚动)delayMillis:每次滚动开始前的等待时长,单位为毫秒velocity:滚动速度,单位为dp/秒
方案2:自定义实现(兼容低版本Compose)
如果项目使用的Compose版本低于1.4.0,可以通过自定义动画修饰符实现:
首先定义跑马灯修饰符:
import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.RepeatMode import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.tween import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.text.TextLayoutResult fun Modifier.marquee( scrollSpeed: Dp = 30.dp, delayBeforeScroll: Int = 1000 ): Modifier = composed { var containerWidth by remember { mutableStateOf(0) } var textWidth by remember { mutableStateOf(0) } val transition = rememberInfiniteTransition(label = "marquee") val scrollOffset by transition.animateFloat( initialValue = 0f, targetValue = if (textWidth > containerWidth) -(textWidth - containerWidth).toFloat() else 0f, animationSpec = infiniteRepeatable( animation = tween( durationMillis = ((textWidth - containerWidth) / scrollSpeed.value * 1000).toInt(), delayMillis = delayBeforeScroll, easing = LinearEasing ), repeatMode = RepeatMode.Restart ), label = "scrollOffset" ) this .onSizeChanged { containerWidth = it.width } .graphicsLayer { translationX = scrollOffset } }
使用方式:
var textLayoutResult by remember { mutableStateOf<TextLayoutResult?>(null) } Text( text = "超长文本超长文本超长文本超长文本超长文本超长文本", modifier = Modifier .fillMaxWidth() .marquee(), maxLines = 1, onTextLayout = { textLayoutResult = it }, overflow = TextOverflow.Clip )
内容的提问来源于stack exchange,提问作者Jéluchu
相关产品推荐
相关产品推荐

