gradually_print_text.dart 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import 'dart:async';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. class GraduallyPrintText extends StatefulWidget {
  5. const GraduallyPrintText({
  6. super.key,
  7. this.initTxt,
  8. required this.graduallyController,
  9. this.textStyle,
  10. });
  11. final TextStyle? textStyle;
  12. final GraduallyController graduallyController;
  13. final String? initTxt;
  14. @override
  15. State<GraduallyPrintText> createState() => _GraduallyPrintTextState();
  16. }
  17. typedef GraduallyTxtListener = void Function(String txt);
  18. class GraduallyController {
  19. String graduallyTxt = '';
  20. int progressIndex = 0;
  21. Timer? appendTimer;
  22. bool? isAppendDone;
  23. bool? isShowDone;
  24. Duration printSpeed;
  25. GraduallyTxtListener? listener;
  26. VoidCallback? finishedListener;
  27. GraduallyController({this.printSpeed = const Duration(milliseconds: 60)});
  28. setGraduallyTxtListener(GraduallyTxtListener listener) {
  29. this.listener = listener;
  30. }
  31. setGraduallyFinishedListener(VoidCallback finishedListener) {
  32. this.finishedListener = finishedListener;
  33. }
  34. append(String txt) {
  35. graduallyTxt += txt;
  36. _startAppend();
  37. }
  38. void _initAppend() {
  39. progressIndex = 0;
  40. isAppendDone = null;
  41. isShowDone = null;
  42. appendTimer = null;
  43. }
  44. appendDone() {
  45. isAppendDone = true;
  46. // debugPrint('GraduallyMdText: appendDone');
  47. }
  48. _startAppend() {
  49. if (appendTimer != null) {
  50. return;
  51. }
  52. _initAppend();
  53. appendTimer = Timer.periodic(printSpeed, (timer) {
  54. // debugPrint('GraduallyMdText-progressIndex: $progressIndex');
  55. if (progressIndex < graduallyTxt.length) {
  56. progressIndex += 1;
  57. listener?.call(graduallyTxt.substring(0, progressIndex));
  58. } else if (isAppendDone == true) {
  59. // debugPrint('GraduallyMdText: appendTimer done');
  60. dispose();
  61. finishedListener?.call();
  62. }
  63. });
  64. }
  65. dispose() {
  66. appendTimer?.cancel();
  67. isAppendDone = null;
  68. isShowDone = true;
  69. appendTimer = null;
  70. }
  71. }
  72. class _GraduallyPrintTextState extends State<GraduallyPrintText> {
  73. String mdTxt = '';
  74. @override
  75. void initState() {
  76. super.initState();
  77. mdTxt = widget.initTxt ?? '';
  78. widget.graduallyController.setGraduallyTxtListener((txt) {
  79. if (mounted) {
  80. setState(() {
  81. mdTxt = txt;
  82. });
  83. }
  84. });
  85. }
  86. @override
  87. void dispose() {
  88. super.dispose();
  89. }
  90. @override
  91. Widget build(BuildContext context) {
  92. return SelectionArea(
  93. child: Text(
  94. mdTxt,
  95. style: widget.textStyle,
  96. ),
  97. );
  98. }
  99. }