Измените цветовую часть текста с помощью индекса во флаттере

#flutter

Вопрос:

У меня есть одна строка, которая содержит слова: achievement admission advertise pencil . У меня есть список с парами чисел:

 class Pair<T1, T2> {
  final T1 a;
  final T2 b;

  Pair(this.a, this.b);
}
String letters = "achievement admission advertise pencil";
List<Pair> words = [Pair(3, 5), Pair(6, 8), Pair(9, 11), Pair(12, 14), Pair(15, 17)];
 

Я хочу изменить цветовую часть строки, используя индекс от какого знака к какому знаку. Например, через 2 секунды буквы от 3 до 5 должны иметь зеленый цвет. Через следующие 2 секунды только буквы от 6 до 8 должны быть зелеными, через следующие 2 секунды только буквы от 9 до 11 должны быть зелеными, остальные буквы должны вернуться к черному. Есть ли какой-нибудь способ сделать это?

Ответ №1:

Да, вы можете создать для этого пользовательский виджет. Вот рабочий пример:

(Использовать с SyllableText(text: letters, parts: words) )

 class SyllableText extends StatefulWidget {
  const SyllableText({
    required this.text,
    required this.parts,
    Key? key,
  }) : super(key: key);

  final String text;
  final List<Pair> parts;

  @override
  SyllableTextState createState() => SyllableTextState();
}

class SyllableTextState extends State<SyllableText> {
  int currentPartIndex = 0;

  @override
  void initState() {
    super.initState();
    Future.doWhile(() async {
      await Future.delayed(Duration(seconds: 2));
      if (mounted amp;amp; currentPartIndex < widget.parts.length) {
        setState(() => currentPartIndex  );
        return true;
      } else {
        return false;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    if (currentPartIndex < widget.parts.length) {
      final part = widget.parts[currentPartIndex];
      final startText = widget.text.substring(0, part.a);
      final coloredText = widget.text.substring(part.a, part.b   1);
      final endText = widget.text.substring(part.b   1);
      return Text.rich(
        TextSpan(
          children: [
            TextSpan(text: startText),
            TextSpan(text: coloredText, style: TextStyle(color: Colors.green)),
            TextSpan(text: endText),
          ],
        ),
      );
    } else {
      return Text(widget.text);
    }
  }
}