Flutter – TypeWriter Text Effect
In this Flutter article, let’s learn how to create Animated TypeWritting Effect on a flutter Text Widget. The typewriter effect is a kind of animation where the text appears to be typed out letter by letter. This is often used in games, movies, videos, or in certain apps where you want the user’s attention to focus on some text.
Step By Step Implementation
Step 1: Create a New Project in Android Studio
To set up Flutter Development on Android Studio please refer to Android Studio Setup for Flutter Development, and then create a new project in Android Studio please refer to Creating a Simple Application in Flutter.
Step 2: Inside Scaffold Widget
- Create an Appbar
- Add a Text Widget and give text style to it and align it to the center-left
- Add FloatingActionButton to it
Dart
import 'dart:ui' ; import 'package:flutter/cupertino.dart' ; import 'package:flutter/material.dart' ; void main() { runApp( const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'w3wiki' , theme: ThemeData( primarySwatch: Colors.green ), home: const TypeWritterText(), ); } } class TypeWritterText extends StatefulWidget { const TypeWritterText({ Key? key }) : super(key: key); @override State<TypeWritterText> createState() => _TypeWritterTextState(); } class _TypeWritterTextState extends State<TypeWritterText> { @override Widget build(BuildContext context) { return Scaffold( // create an Appbar appBar: AppBar( title: Text( "GeekforBeginner" ), centerTitle: true , ), // Add Text widget, giving it align // property and text style body: Center( child: Container( padding: const EdgeInsets.all(20), width: double .infinity, child: Align( alignment: Alignment.centerLeft, child: Text( 'Type Writer Text effect' , style: TextStyle( fontSize: 24, fontStyle: FontStyle.italic, fontWeight: FontWeight.bold ), ), ), ), ), // floating action button floatingActionButton: FloatingActionButton( onPressed: (){ }, child: const Icon(Icons.play_arrow), ), ); } } |
Output:
Step 3: Initialize 2 variables of type int and set the default value 0
Dart
import 'dart:ui' ; import 'package:flutter/cupertino.dart' ; import 'package:flutter/material.dart' ; void main() { runApp( const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'w3wiki' , theme: ThemeData( primarySwatch: Colors.green ), home: const TypeWritterText(), ); } } class TypeWritterText extends StatefulWidget { const TypeWritterText({ Key? key }) : super(key: key); @override State<TypeWritterText> createState() => _TypeWritterTextState(); } class _TypeWritterTextState extends State<TypeWritterText> { // initializing 2 variables and // setting it's value to 0 int _currentIndex = 0; int _currentCharIndex = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( "GeekforBeginner" ), centerTitle: true , ), body: Center( child: Container( padding: const EdgeInsets.all(20), width: double .infinity, child: Align( alignment: Alignment.centerLeft, child: Text( 'Type Writer Text effect' , style: TextStyle( fontSize: 24, fontStyle: FontStyle.italic, fontWeight: FontWeight.bold ), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: (){ }, child: const Icon(Icons.play_arrow), ), ); } } |
Step 4: Create a list of String
Dart
import 'dart:ui' ; import 'package:flutter/cupertino.dart' ; import 'package:flutter/material.dart' ; void main() { runApp( const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'w3wiki' , theme: ThemeData(primarySwatch: Colors.green), home: const TypeWritterText(), ); } } class TypeWritterText extends StatefulWidget { const TypeWritterText({Key? key}) : super(key: key); @override State<TypeWritterText> createState() => _TypeWritterTextState(); } class _TypeWritterTextState extends State<TypeWritterText> { // initializing 2 variables int _currentIndex = 0; int _currentCharIndex = 0; // creating List of String final List<String> _strings = [ "Welcome to w3wiki" , "Get Programming Solution Here" , "And more..." , ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( "GeekforBeginner" ), centerTitle: true , ), body: Center( child: Container( padding: const EdgeInsets.all(20), width: double .infinity, child: Align( alignment: Alignment.centerLeft, child: Text( 'Type Writer Text effect' , style: TextStyle( fontSize: 24, fontStyle: FontStyle.italic, fontWeight: FontWeight.bold), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: () {}, child: const Icon(Icons.play_arrow), ), ); } } |
Step 5: Create a function _typeWrittingAnimation()
Create Future delay to iterate through the function continuously by 50 milliseconds
Dart
import 'dart:ui' ; import 'package:flutter/cupertino.dart' ; import 'package:flutter/material.dart' ; void main() { runApp( const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'w3wiki' , theme: ThemeData(primarySwatch: Colors.green), home: const TypeWritterText(), ); } } class TypeWritterText extends StatefulWidget { const TypeWritterText({Key? key}) : super(key: key); @override State<TypeWritterText> createState() => _TypeWritterTextState(); } class _TypeWritterTextState extends State<TypeWritterText> { // initializing 2 variables int _currentIndex = 0; int _currentCharIndex = 0; // creating List final List<String> _strings = [ "Welcome to w3wiki" , "Get Programming Solution Here" , "And more..." , ]; // creating a function and future delay for iteration void _typeWrittingAnimation(){ if (_currentCharIndex < _strings[_currentIndex].length){ _currentCharIndex++; } else { _currentIndex = (_currentIndex+1)% _strings.length; _currentCharIndex = 0; } setState(() { }); Future.delayed( const Duration(milliseconds: 50),(){ _typeWrittingAnimation(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( "GeekforBeginner" ), centerTitle: true , ), body: Center( child: Container( padding: const EdgeInsets.all(20), width: double .infinity, child: Align( alignment: Alignment.centerLeft, child: Text( 'Type Writer Text effect' , style: TextStyle( fontSize: 24, fontStyle: FontStyle.italic, fontWeight: FontWeight.bold), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: () {}, child: const Icon(Icons.play_arrow), ), ); } } |
Step 6: Calling the function
Whenever the floating action button is pressed the _typeWrittingAnimation() function will be called and the text will be typed out letter by letter.
Dart
import 'dart:ui' ; import 'package:flutter/cupertino.dart' ; import 'package:flutter/material.dart' ; void main() { runApp( const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'w3wiki' , theme: ThemeData(primarySwatch: Colors.green), home: const TypeWritterText(), ); } } class TypeWritterText extends StatefulWidget { const TypeWritterText({Key? key}) : super(key: key); @override State<TypeWritterText> createState() => _TypeWritterTextState(); } class _TypeWritterTextState extends State<TypeWritterText> { // initializing 2 variables int _currentIndex = 0; int _currentCharIndex = 0; // creating List final List<String> _strings = [ "Welcome to w3wiki" , "Get Programming Solution Here" , "And more..." , ]; // creating a function and future delay for iteration void _typeWrittingAnimation(){ if (_currentCharIndex < _strings[_currentIndex].length){ _currentCharIndex++; } else { _currentIndex = (_currentIndex+1)% _strings.length; _currentCharIndex = 0; } setState(() { }); Future.delayed( const Duration(milliseconds: 50),(){ _typeWrittingAnimation(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( "GeekforBeginner" ), centerTitle: true , ), body: Center( child: Container( padding: const EdgeInsets.all(20), width: double .infinity, child: Align( alignment: Alignment.centerLeft, child: Text( 'Type Writer Text effect' , style: TextStyle( fontSize: 24, fontStyle: FontStyle.italic, fontWeight: FontWeight.bold), ), ), ), ), // whenever the floating action button is // pressed the _typeWrittingAnimation() // function will be called floatingActionButton: FloatingActionButton( onPressed: _typeWrittingAnimation, child: const Icon(Icons.play_arrow), ), ); } } |
Step 7: Using string in the Text widget with the help of substring
Dart
import 'dart:ui' ; import 'package:flutter/cupertino.dart' ; import 'package:flutter/material.dart' ; void main() { runApp( const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'w3wiki' , theme: ThemeData(primarySwatch: Colors.green), home: const TypeWritterText(), ); } } class TypeWritterText extends StatefulWidget { const TypeWritterText({Key? key}) : super(key: key); @override State<TypeWritterText> createState() => _TypeWritterTextState(); } class _TypeWritterTextState extends State<TypeWritterText> { // initializing 2 variables int _currentIndex = 0; int _currentCharIndex = 0; // creating List final List<String> _strings = [ "Welcome to w3wiki" , "Get Programming Solution Here" , "And more..." , ]; // creating a function and future delay for iteration void _typeWrittingAnimation() { if (_currentCharIndex < _strings[_currentIndex].length) { _currentCharIndex++; } else { _currentIndex = (_currentIndex + 1) % _strings.length; _currentCharIndex = 0; } setState(() {}); Future.delayed( const Duration(milliseconds: 50), () { _typeWrittingAnimation(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( "GeekforBeginner" ), centerTitle: true , ), body: Center( child: Container( padding: const EdgeInsets.all(20), width: double .infinity, child: Align( alignment: Alignment.centerLeft, // Using string in the Text widget // with the help of substring child: Text( _strings[_currentIndex].substring(0, _currentCharIndex), style: TextStyle( fontSize: 24, fontStyle: FontStyle.italic, fontWeight: FontWeight.bold), ), ), ), ), // whenever the floating action button is // pressed the _typeWrittingAnimation() // function will be called floatingActionButton: FloatingActionButton( onPressed: _typeWrittingAnimation, child: const Icon(Icons.play_arrow), ), ); } } |
Output:
Explanation:
- The main point here is the _typeWrittingAnimation() function.
- The function sets the state to increment the _currentCharIndex variable by 1 and calls itself after a delay of 50 milliseconds.
- When _currentCharIndex reaches the end of the string, the code resets it to 0 and sets the _currentIndex to the next string in the list.
- The text displayed in the Container is now just a portion of the full string, from the beginning up to the current character using Substring Method.
- This creates the appearance of the text being typed out letter by letter.