Flutter开发笔记 —— 打字机文本效果实战

前言

今天逛掘金,突然看到一个打字机相关功能的一篇文章,想着自己也实现下,功能很简单,话不多说,看正文。

功能分析

打字机的功能效果有哪些

  • 最终文本
  • 当前文本
  • 闪烁光标

最后我们根据自己的实际需求定义秒数展示即可。

功能实现

最终文本、当前文本用两个变量进行处理,我们下文围绕着光标处理讲述

光标功能

光标功能闪烁:我们可以用动画配合透明度进行实现(毫秒数根据自己喜好调整)

动画相关实现

  AnimationController? controller;
  Animation<double>? animationValue;

 @override
  void initState() {

    controller = AnimationController(vsync: this,duration: Duration(milliseconds: 300));
    animationValue = Tween<double>(begin: 0,end: 1).animate(controller!);
    controller!.addListener(() {
      if(controller!.isCompleted){
        controller!.reset();
      }
    });
    animationTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
      if(currentText.length >= text.length){
        timer.cancel();
        return;
      }
      controller!.forward();
    });
    controller!.forward();
    // controller!.repeat();
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    controller!.dispose();
    // TODO: implement dispose
    super.dispose();
  }

动画实现后,我们在视图中添加文本标识即可

            AnimatedBuilder(
                animation: controller!,
                builder: (context,widget){
                  return Opacity(
                    opacity: animationValue!.value,
                    child: Container(
                      child: Text(
                        "|",
                        style: TextStyle(
                          color: Colors.black,
                          fontSize: 25
                        ),
                      ),
                    ),
                  );
            }),

文本展示

我们前面提到,我们做打字机需要一个最终文本以及当前展示的文本,我们需要配合定时器并且追加每个新的字符串至展示文本中

定义文本追加方法


int count = 0;
  /*
   * @author Marinda
   * @date 2024/7/15 16:19
   * @description 修改文本方法
   */
  changeText(){
    String targetText = text.substring(count,count+1);
    setState(() {
      currentText += targetText;
      count++;
    });
    print("当前添加文本为:${targetText}");
    controller!.forward();
  }

之后在我们的initState方法中定义计时器进行更新

    textTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
      if(currentText.length >= text.length){
        timer.cancel();
        return;
      }
      changeText();
    });

之后我们在视图中追加显示文本控件即可

            Container(
              child: Text(
                  "$currentText",
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 24
                ),
              ),
            ),

最终代码

import 'dart:async';

import 'package:flutter/material.dart';

class Example01 extends StatefulWidget{


  @override
  State<StatefulWidget> createState() {
    return Example01State();
  }

}

class Example01State extends State<Example01> with TickerProviderStateMixin{

  String text = "Hello World This a text ...";
  String currentText = "";
  bool showLoadingFlag = false;
  int count = 0;
  Timer? textTimer;
  Timer? animationTimer;
  AnimationController? controller;
  Animation<double>? animationValue;


  @override
  void initState() {

    controller = AnimationController(vsync: this,duration: Duration(milliseconds: 300));
    animationValue = Tween<double>(begin: 0,end: 1).animate(controller!);
    textTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
      if(currentText.length >= text.length){
        timer.cancel();
        return;
      }
      changeText();
    });
    controller!.addListener(() {
      if(controller!.isCompleted){
        controller!.reset();
      }
    });
    animationTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
      if(currentText.length >= text.length){
        timer.cancel();
        return;
      }
      controller!.forward();
    });
    controller!.forward();
    // controller!.repeat();
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    controller!.dispose();
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child:Row(
          children: [
            Container(
              child: Text(
                  "$currentText",
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 24
                ),
              ),
            ),
            AnimatedBuilder(
                animation: controller!,
                builder: (context,widget){
                  return Opacity(
                    opacity: animationValue!.value,
                    child: Container(
                      child: Text(
                        "|",
                        style: TextStyle(
                          color: Colors.black,
                          fontSize: 25
                        ),
                      ),
                    ),
                  );
            }),
          ],
        ),
      )
    );
  }

  /*
   * @author Marinda
   * @date 2024/7/15 16:19
   * @description 修改文本方法
   */
  changeText(){
    String targetText = text.substring(count,count+1);
    setState(() {
      currentText += targetText;
      count++;
    });
    print("当前添加文本为:${targetText}");
    controller!.forward();
  }
}

效果

结束语

感谢你的观看。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇