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

Flutter中如何根据索引动态定时修改字符串部分文本的颜色

实现方案

这是Flutter端的落地实现,核心通过RichText实现同一段文本多样式渲染,配合Timer实现定时切换高亮区间:

完整可运行代码

import 'package:flutter/material.dart';
import 'dart:async';

// 自定义Pair类
class Pair<T1, T2> {
  final T1 a;
  final T2 b;

  Pair(this.a, this.b);
}

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("分段高亮文本")),
        body: const HighlightTextDemo(),
      ),
    );
  }
}

class HighlightTextDemo extends StatefulWidget {
  const HighlightTextDemo({super.key});

  @override
  State<HighlightTextDemo> createState() => _HighlightTextDemoState();
}

class _HighlightTextDemoState extends State<HighlightTextDemo> {
  final String letters = "achievement admission advertise pencil";
  final List<Pair> words = [Pair(3, 5), Pair(6, 8), Pair(9, 11), Pair(12, 14), Pair(15, 17)];
  // 当前高亮的区间下标,-1表示初始状态无高亮
  int _currentHighlightIndex = -1;
  Timer? _timer;

  @override
  void initState() {
    super.initState();
    _initTimer();
  }

  void _initTimer() {
    // 首次延迟2秒触发第一个区间高亮
    Future.delayed(const Duration(seconds: 2), () {
      if (!mounted) return;
      setState(() => _currentHighlightIndex = 0);
      // 之后每2秒切换下一个高亮区间
      _timer = Timer.periodic(const Duration(seconds: 2), (timer) {
        if (_currentHighlightIndex < words.length - 1) {
          setState(() => _currentHighlightIndex++);
        } else {
          // 所有区间遍历完成后停止定时器,如需循环高亮可将此处改为 _currentHighlightIndex = 0
          timer.cancel();
        }
      });
    });
  }

  Widget _buildMultiStyleText() {
    // 初始无高亮状态全黑展示
    if (_currentHighlightIndex == -1) {
      return Text(
        letters,
        style: const TextStyle(color: Colors.black, fontSize: 18),
      );
    }
    // 取出当前需要高亮的区间
    Pair currentRange = words[_currentHighlightIndex];
    int start = currentRange.a as int;
    int end = currentRange.b as int;
    return RichText(
      text: TextSpan(
        style: const TextStyle(fontSize: 18, color: Colors.black),
        children: [
          TextSpan(text: letters.substring(0, start)),
          TextSpan(text: letters.substring(start, end), style: const TextStyle(color: Colors.green)),
          TextSpan(text: letters.substring(end)),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: _buildMultiStyleText(),
    );
  }

  @override
  void dispose() {
    // 页面销毁时取消定时器避免内存泄漏
    _timer?.cancel();
    super.dispose();
  }
}

核心逻辑说明

  • 状态管理:通过_currentHighlightIndex记录当前需要高亮的区间下标,初始值为-1实现默认全黑效果
  • 定时器逻辑:首次延迟2秒触发第一段高亮,之后每2秒切换下一个区间,遍历完全部区间后自动停止,可按需修改为循环模式
  • 文本拼接:利用Dart字符串substring左闭右开的特性,和需求给定的区间规则完全匹配,无需额外偏移计算,直接拆分出黑色前缀、绿色高亮段、黑色后缀三部分拼接即可
  • 边界处理:增加mounted判断、页面销毁时取消定时器,避免页面退出后触发状态更新导致异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:06:02