Photo by Nhu Nguyen on Unsplash

When we start developing our apps in a new language and new technology, we take pride in every keystroke we make. We are learning, we want to know how things work, so we write countless times the same thing over and over again. But after the 100th StatefulWidget , we start wondering if there is a better and faster way to create both the widget and its state.

And here is where Live Templates come to save our lives.

StatefulWidget Live Template

A Live Template is basically a template that we can use for various tasks, like for loops, creating Widgets , variable declarations and common class declarations. In fact, some of these are already in IntelliJ, like iter for iterating in a list of objects.

To test it out, inside a function we type in iter , click enter, and start typing in each variable. To navigate to the next variable, we click on the tab bar.

iter Live Template in action

By going to the Android Studio Preferences ( CMD + , on Mac and Control + Alt + S on Windows) and searching for Live Templates we can see a list of all the available templates for each language or technology.

To start with a simple example, we open the Dart live templates and search for iter .

iter Live Template preferences

As we can see, we have:

An abbreviation, to be used to “call” the template, in this case it’s iter

A description to show the user what this Live Template will do

A snippet of code

A button called “Edit Variables”

Miscellaneous options.

For now, we’ll focus on the code snippet for this example:

In this code snippet, we have a for-each loop made in dart with 3 variables. Each variable is inside two $ symbols, with their name in upper-case and we can see that one of them is called $END$ , which is a variable to set the place for the cursor after the user finishes using the Live Template.

Creating a Live Template for StatefulWidgets

So how can we make a live template?

Taking as an example the StatefulWidget , (let’s forget that Flutter already has a Live Template for it with the keywords stful ) I suggest that we start by creating it manually.

The name LiveWidget is present both in the class declaration and inside of the _LiveWidgetState name, so we can easily state that LiveWidget is a variable. Since our variables will need to be inside two $ , we can name them $CLASS_NAME$ .

We then need to change all places where the class name appears:

The StatefulWidget class name

class name The createState return type

return type The State class name

class name The State extended type

Let’s open again the Live Template preferences so that we can add it there:

Creating a new Live Template

In the newly created template, we will need to fill in each field:

For the abbreviation, I’ve chosen statewidget

A small description for the template could be Creates a stateful widget

Finally, we must paste our code snippet

“No applicable contexts yet” error

However we can see an error message in the bottom of the screen: “No applicable contexts yet”. If we click on define, we are prompted with a list of languages with the subcategories Statement , Top-level and Other .

Available contexts for Dart

Since we want to do a class declaration, we will want our Live Template to only be available at Top Level , and so we choose that option.

And that’s it! We can now click apply and start testing our live template!

We create a new file, test out the template by typing in the abbreviation, fill in the class name and…!

StatefulWidget undefined class error

We got undefined class errors.

To solve this, we must edit our Live Template to also import from flutter/material , in case we are using Material Widgets.

And now, finally everything is working in order!

The next step would be removing the null return from the build method and putting in the $END$ variable as we saw with the iter example, so that we can start writing the widget code directly:

Advanced usage: Creating a template for built_value classes

For a more complex example, let’s take a look into built_value classes.

In order to serialize and deserialize our classes with built_value , we need to create some boilerplate code:

However, it is not straightforward creating this Live Template:

We have the file name in part 'data_class.g.dart';

in When declaring the serializer, we need to declare it as _$dataClassSerializer , and as we can see, it camel cases DataClass in order to create dataClass

Is there a way to fix this?

If we look into our previous example, in the Live Template settings window, we have a button called Edit Variables with several options available

StatefulWidget Live Template variables

Name - the name of the variable that we created. Each time we create a new variable, a row is automatically created here with its name

- the name of the variable that we created. Each time we create a new variable, a row is automatically created here with its name Expression - a set of expressions that can be applied to our variable, such as camelCase , date , user and fileNameWithoutExtension

- a set of expressions that can be applied to our variable, such as , , and Default Value - a value that is set by default but can be edited by the user afterwards. The interesting part here is that we can reference other variables here

- a value that is set by default but can be edited by the user afterwards. The interesting part here is that we can reference other variables here Skip if defined - If the value is already defined by a Default Value , then we can skip it.

How can this help us?

First, we will need to declare a new variable for part called $FILE_NAME$ . As the default value, we need to use the Expression fileNameWithoutExtension , and, since we don’t want this variable to be edited by the user, we check the Skip if needed checkbox.

Then, in your code, declare the $CLASS_NAME$ variable so that it automatically appears in the variables window. This will be used to create our last variable, $STATIC_CLASS_NAME$ . This variable will use a default value that will combine the Expression camelCase and the variable CLASS_NAME : camelCase(CLASS_NAME) . As with the first variable, the user won’t edit this variable, so we check the Skip if needed checkbox.

As a side note, since built_value uses a variable name with the character $ , it must be declared as $$ , so, for the STATIC_CLASS_NAME we declare _$$$STATIC_CLASS_NAME$Serializer .

We end up with the following live template:

built_value Variables

And so, we can test it:

built_value Live Template in action

Recap and Future Possibilities

We finished our shallow dive into Live Templates! 🥳

But what other uses will we have for it?

Try to look at your codebase and see what boilerplate you need to write and write again. I’ll give you some more examples from my projects:

Declaring RxDart Subject s and the needed Sink and/or Stream

s and the needed and/or Variables used in intl translation package

translation package Creating a bloc by extending a BaseBloc with the necessary constructor

with the necessary constructor Creating mapper classes

I’m curious, what are you going to use it for?