OhMad
OhMad

Reputation: 7299

Flutter - Typing Text animation

For each of my text widgets, I actually want the text to type in instead of displaying it right away. Is there a simpler approach than using a variable and adding to it inside of setState() ?

Thanks

Upvotes: 7

Views: 13766

Answers (3)

Anandh Krishnan
Anandh Krishnan

Reputation: 6002

A very easiest way with custom duration, use this plugin animated_text_kit: ^4.2.1

import 'package:animated_text_kit/animated_text_kit.dart';

and the code you have to use is

 SizedBox(
    width: 250.0,
    child: DefaultTextStyle(
      style: const TextStyle(
        fontSize: 30.0,
        fontFamily: 'popin',
      ),
      child: AnimatedTextKit(isRepeatingAnimation: true, animatedTexts: [
        TyperAnimatedText('When you talk, you are only repeating',
            speed: Duration(milliseconds: 100)),
        TyperAnimatedText('something you know.But if you listen,',
            speed: Duration(milliseconds: 100)),
      ]),
    ),
  ),

enter image description here

Upvotes: 0

Arun R. Prajapati
Arun R. Prajapati

Reputation: 2802

you can use this Plugin

animated_text_kit:

Examples : https://github.com/aagarwal1012/Animated-Text-Kit

A piece of Code :

 SizedBox(
  width: 250.0,
  child: TypewriterAnimatedTextKit(
    onTap: () {
        print("Tap Event");
      },
    text: [
      "Discipline is the best tool",
      "Design first, then code",
      "Do not patch bugs out, rewrite them",
      "Do not test bugs out, design them out",
    ],
    textStyle: TextStyle(
        fontSize: 30.0,
        fontFamily: "Agne"
    ),
    textAlign: TextAlign.start,
    alignment: AlignmentDirectional.topStart // or Alignment.topLeft
  ),
);

Upvotes: 5

Collin Jackson
Collin Jackson

Reputation: 116788

This might be a good use case for an AnimatedBuilder. That will allow you to more easily control the duration of the typing animation and only rebuild your widget when the length changes. Here's an example of how to do that.

screenshot

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primaryColor: const Color.fromARGB(255, 0, 199, 0),
        accentColor: const Color.fromARGB(255, 222, 233, 226),
        brightness: Brightness.dark,
        canvasColor: Colors.black,
      ),
      home: new MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  State createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {

  Animation<int> _characterCount;

  int _stringIndex;
  static const List<String> _kStrings = const <String>[
    'Call trans opt: received. 2-19-98 13:24:18 REC:Log>',
    'Trace program running.',
    '[312]555-0690',
  ];
  String get _currentString => _kStrings[_stringIndex % _kStrings.length];

  @override
  Widget build(BuildContext context) {
    ThemeData theme = Theme.of(context);
    TextStyle textStyle = theme.textTheme.title.copyWith(
      fontFamily: 'Courier New',
      color: theme.primaryColor,
    );
    return new Scaffold(
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.navigate_next),
        onPressed: () async {
          AnimationController controller = new AnimationController(
            duration: const Duration(milliseconds: 4000),
            vsync: this,
          );
          setState(() {
            _stringIndex = _stringIndex == null ? 0 : _stringIndex + 1;
            _characterCount = new StepTween(begin: 0, end: _currentString.length)
              .animate(new CurvedAnimation(parent: controller, curve: Curves.easeIn));
          });
          await controller.forward();
          controller.dispose();
        },
      ),
      body: new Container(
        margin: new EdgeInsets.symmetric(vertical: 50.0, horizontal: 10.0),
        child: _characterCount == null ? null : new AnimatedBuilder(
          animation: _characterCount,
          builder: (BuildContext context, Widget child) {
            String text = _currentString.substring(0, _characterCount.value);
            return new Text(text, style: textStyle);
          },
        ),
      ),
    );
  }
}

If you plan to use this animated text widget a lot, you could refactor it into a separate class using AnimatedWidget.

Upvotes: 24

Related Questions