You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android使用Span实现Loading尾随圆点动画无效果如何解决

问题原因

你的代码存在3处核心错误导致效果无法实现:

  1. 类型转换异常:调用setText时传入的是SpannableStringBuilder实例,但动画回调里强行将textView.text转为SpannableString,会触发运行时异常,后续逻辑全部无法执行,是圆点完全不显示的核心原因。
  2. Span逻辑错误:仅给需要显示的圆点设置前景色,没有隐藏不需要显示的圆点,无法实现圆点逐个出现的效果。
  3. 动画配置错误:repeatCount = 10只会重复10次后停止,无法无限循环;4000ms的总时长也会导致动画切换太慢。

修正后可运行代码

val text = "Loading"
// 初始化包含3个圆点的文本
val fullText = "$text..."
val spannedText = SpannableStringBuilder(fullText)
binding.textViewTitle.setText(spannedText, TextView.BufferType.SPANNABLE)

ValueAnimator.ofInt(0, 4).apply {
    repeatCount = ValueAnimator.INFINITE // 无限循环
    repeatMode = ValueAnimator.RESTART // 循环到终点后回到起点重新开始
    duration = 1200 // 总时长1.2s,每个状态间隔300ms,可按需调整
    addUpdateListener { animator ->
        val dotsCount = animator.animatedValue as Int
        val textSpan = binding.textViewTitle.text as SpannableStringBuilder
        // 先清除旧的前景色Span
        textSpan.getSpans(0, textSpan.length, ForegroundColorSpan::class.java)
            .forEach { textSpan.removeSpan(it) }
        // 把超出当前显示数量的圆点设为透明(如果你的TextView有背景色,也可以换成和背景相同的颜色)
        if (dotsCount < 3) {
            textSpan.setSpan(
                ForegroundColorSpan(Color.TRANSPARENT),
                text.length + dotsCount,
                fullText.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }
        // 无需手动调用invalidate,修改Span后TextView会自动刷新
    }
}.start()

关键优化说明

  • 统一使用SpannableStringBuilder处理可编辑Span文本,避免类型转换错误
  • 每次动画更新前先清除旧Span,避免多个Span叠加导致效果异常
  • 通过将不需要显示的圆点设为透明实现隐藏效果,无需频繁修改文本内容,性能更高

内容的提问来源于stack exchange,提问作者Henrique Vasconcellos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:15:00