typewriter_text.dart 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. class TypewriterText extends StatefulWidget {
  4. final String text; // 要显示的完整文本
  5. final TextStyle? style; // 字体样式
  6. final Duration speed; // 每个字出现的速度
  7. final VoidCallback? onComplete; // 打字完成回调
  8. final bool repeat; // 是否循环播放
  9. const TypewriterText({
  10. super.key,
  11. required this.text,
  12. this.style,
  13. this.speed = const Duration(milliseconds: 80),
  14. this.onComplete,
  15. this.repeat = false,
  16. });
  17. @override
  18. _TypewriterTextState createState() => _TypewriterTextState();
  19. }
  20. class _TypewriterTextState extends State<TypewriterText> {
  21. String _displayedText = '';
  22. int _charIndex = 0;
  23. Timer? _timer;
  24. @override
  25. void initState() {
  26. super.initState();
  27. _startTyping();
  28. }
  29. void _startTyping() {
  30. _displayedText = '';
  31. _charIndex = 0;
  32. _timer?.cancel();
  33. _timer = Timer.periodic(widget.speed, (timer) {
  34. if (_charIndex < widget.text.length) {
  35. setState(() {
  36. _displayedText += widget.text[_charIndex];
  37. });
  38. _charIndex++;
  39. } else {
  40. _timer?.cancel();
  41. widget.onComplete?.call();
  42. if (widget.repeat) {
  43. Future.delayed(Duration(seconds: 1), _startTyping);
  44. }
  45. }
  46. });
  47. }
  48. @override
  49. void dispose() {
  50. _timer?.cancel();
  51. super.dispose();
  52. }
  53. @override
  54. Widget build(BuildContext context) {
  55. return Text(
  56. _displayedText,
  57. style: widget.style ?? const TextStyle(fontSize: 18),
  58. );
  59. }
  60. }