Navigate back to the homepage

Learning Live Templates for Jetpack Compose

Matt McKenna
April 20th, 2021 · 6 min read

Intro to Live Templates

If you are like me you like to optimize some of the most common situations in your day to day tasks. Finding little ways to make your machine work more for you is satisfying and when it all adds up can lead to some serious time saved!

Android Studio’s live templates are a great and fun way to increase your productivity.

One way to think about live templates are like acronyms. Much like in english “IDK” expands to “I don’t know” a live template can expand from main to:

1fun main(args: Array<String>) {
2 $END$
3}
In the follow parts of this post you’ll learn:
  • To use Live Templates in Android Studio
  • How to create your own Live Templates
  • About the many variables available for Live Templates
  • How to use Live Templates with Jetpack Compose

Let’s dive in!

How to use Live Templates

Android Studio comes with a bunch of live templates out of the box. These can be accessed by going to: Preferences > Editor > Live Templates. Lets see what kind of options we have in this settings screen.

The Live Template settings screen labeled with numbers.
  1. The list of available categories and live template .
  2. Abbreviation: what is typed to trigger the live template.
  3. Template Text: Where the live template is constructed.
  4. Description: A description for what this live template does.
  5. Additional options for this live template.
  6. The “Edit variables” button for this live template.
  7. A context selector to choose where a live template can be invoked.

To use one of these live templates lets make a new kotlin file, type main, and then wait a second. A tool-tip window will show up enabling the insertion of a live template! Press enter or tab to insert.

An example of the main live template being used.

And that’s it! You have now used a Live Template.

Explore some of the example live templates for Kotlin and Android in the settings window to see what else is predefined. In the next section we will learn how to customize one of the preexisting templates to be a bit more useful.

Creating a Custom Live Template

Let’s start by creating a simple live template for a custom TODO comment. I usually put my initials in my TODO’s so that I can easily search them. They look like this:

1// TODO:mcm

To start making this live template follow these steps:

  1. Go to Preferences > Editor > Live Templates
  2. Select the Kotlin group. This is the group the live template will be added to.
  3. Click the + button in the upper right corner.
  4. Select Live Template.
  5. Type the abbreviation to use to trigger the live template.
  6. Give the live template a description.
  7. In the code block, add the code for the live template. In our case it will be the above TODO.
  8. Choose the contexts where this template should be usable.
    1. For this template we want to use it in Kotlin.
    2. And it should be usable in all contexts except comments (since we already add the comment slashes).
A gif demonstration of creating a simple live template.

And that’s it! Here it is in action!

A gif demonstration showing off the custom todo live template.

Live Template Variables

Defining Variables

To define a variable in a live template simply surround a string with dollar signs. Let’s look at the provided Kotlin interface live template:

1interface $NAME$ {
2 $END$
3}
There are two variables here:
  1. $NAME$
  2. $END$

After invoking the live template with tab the editor places your cursor to define a name for the interface. After entering a value for $NAME$ pressing tab again will take you to the next variable, until you get to the variable $END$. $END$, and a few other variables, are predefined for specific use.

Predefined Variables

  • $DOLLAR$
  • $END$
  • $SELECTION$

The $DOLLAR$ variable is used for inserting a dollar sign ($) into a live template. Think of it like an escape sequence in a String. It will most likely be used in those sorts of situations. To see an example look at the Kotlin live template, soutv (Prints a value to System.out).

1println("$EXPR_COPY$ = $DOLLAR${$EXPR$}")

$END$ is a special live template variable that just signifies the template is done being populated. When pressing tab leads to this variable your cursor will be placed in the $END$’s position and the live template will no longer be active.

$SELECTION$ is a special variable type as it represents text that is highlighted in the editor. For instance to surround a piece of code with parenthesis we could define a live template like this:

1($SELECTION$)

This live template is already defined as P under the Live Templates > surround section, along with a few others.

To trigger a selection live template, select the text you wish to use and then, if you are on mac, press ⌥+⌘+J (Ctrl+Alt+J for windows/linux) to prompt the dialog. Then the applicable live templates will appear! Now you can type the name or select which one to use.

An image showing the usage of the P live template to surround with parenthesis.

Variable Functions

Alright, this is where we get to the true magic of live templates.

In the first section we called out the edit variable button in the live template window. This is where variables gain extra power.

Lets jump to Live Templates > Kotlin > iter and see how it is defined:

1for ($VAR$ in $ITERABLE$) {
2 $END$
3}

To break this down, we have the structure for a Kotlin for loop. Two variables are defined, $VAR$ for the variable name and $ITERABLE$ for the iterable collection. And finally $END$ to place the cursor in the for loop when the live template finishes executing.

Up until now this is exactly how we would define such a structure, but lets super charge it.

Click on the “Edit Variables” button that we saw above in location 6 to bring up this window table containing each of the defined variables.

The Edit Template Variables Window

The Expression column has a drop down menu that provides access to many functions that can make the live template variables smarter. Let’s take a look at the two variables in this tempate.

For the variable ITERABLE we see that there is an expression of kotlinVariable(). This function will make a suggestion for something that can populate this variable. If nothing is found then a Default value can be provided as a suggestion.

For VAR we see it has kotlinSuggestVariableName(). This function is tells the live template to put something like i, s, etc if a type can be inferred or loops are being nested. Here the Default value to suggest is i.

The last column in this table is “Skip if defined”. Checking this box means that if the function executes and returns a value then this variable is considered defined and the live template will automatically move your the cursor to the next variable.

Lets see these functions in action! I will make a function to print out elements of a List<String>. Since Android Studio knows the list is only of type string it will suggest a variable name of s for VAR. And since we have a variable of type Iterable in our scope the variable ITERABLE will populate with the available val list! Finally, since the check boxes for “Skip if defined” are not enabled, the cursor still goes to each of these variable in case they need to be edited.

An example gif showing the iter live template in action.

There are LOTS of these functions available for live template variables. The function names are pretty descriptive and I recommend looking through the drop down menus to see the options. There is a comprehensive list on the Jetbrains website.

Live Template Pro tips

Options

There are a few options in the bottom right of the live template window which can add additional convenience.

  • Expand with tab
    • Allows for choosing which key will expand a live template
  • Reformat according to code style
    • a checkbox to use the project’s code style when inserting a live template
  • Shorten FQ names
    • FQ stands for Fully Qualified
    • This is a way to automatically import objects or annotations that a live template uses

Automatic Imports with Live Templates

To automatically import with a live template the “Shorten FQ names” checkbox needs to be checked. Then include the fully qualified name in the live template definition.

Here is an example for making a quick test function and not needing to import the @Test annotation:

1@org.junit.Test
2fun $TEST_FUNCTION$() {
3 $END$
4}

Applicable Contexts

Not all live templates should be accesible at all times. For instance, Kotlin live templates shouldn’t be available in a Java context, but we can have even more control than that! Let’s look at the live template to create a function with no return type (void).

The void live template definition and context showing the check boxes for the applicable contexts.

This live template is useful at the levels of:

  • top-level
  • statement
  • class

but not at the other levels of:

  • comment
  • expression
  • object declaration
  • other

This means is we can granularly configure when a live template could be applicable. Typing void while in a class will for the live template, but typing void in a comment will not!

In a class:
Using the void live template in a class context where it will trigger.
In a comment:
Using the void live template in a comment context where it will not trigger.

Live Templates for Jetpack Compose

Many of the code structures, syntax, and best practices in Jetpack Compose UI are very repeatable which means this is a great opportunity to create live templates! Android Studio Arctic Fox comes with some Compose live templates, but lets add some common uses that aren’t included.

Private Composable
Abbreviationpcomp
DescriptionCreate a private composable function
Shorten FQ Names
1@androidx.compose.runtime.Composable
2private fun $NAME$() {
3 $END$
4}
Remember mutableStateOf delegate
Abbreviationremstate
DescriptionCreate a remember mutableStateOf Delegate
Shorten FQ Names
1val $VAR$ by androidx.compose.runtime.remember {
2 androidx.compose.runtime.mutableStateOf($END$)
3}
Make a Spacer
Abbreviationspacer
DescriptionMakes a spacer of set width
Shorten FQ Names
1androidx.compose.foundation.layout.Spacer(Modifier.width($NUM$.dp))
2$END$
LazyColumn
Abbreviationlazycol
DescriptionMakes a LazyColumn Composable
Shorten FQ Names
Edit Variables Values
NameMOD
ExpressionvariableOfType(androidx.compose.ui.Modifier)
Default"androidx.compose.ui.Modifier"
Skip if definedUnchecked
NameLIST
ExpressionkotlinVariable()
Default
Skip if definedUnchecked
1androidx.compose.foundation.lazy.LazyColumn(modifier = $MODIFIER$) {
2 items(items = $LIST$) { item ->
3 $END$
4 }
5)
Day / Night Preview Composable

This live template idea is from Adam McNeilly

Abbreviationdnprev
DescriptionCreate a day/night @Preview composable function
Shorten FQ Names
1@androidx.compose.ui.tooling.preview.Preview(
2 name = "Night Mode",
3 uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES,
4)
5@androidx.compose.ui.tooling.preview.Preview(
6 name = "Day Mode",
7 uiMode = android.content.res.Configuration.UI_MODE_NIGHT_NO,
8)
9@androidx.compose.runtime.Composable
10private fun $NAME$Preview() {
11 $NAME$($END$)
12}
Phone Preview Annotation

This series of @Preview annotation live templates is inspired by William Barbosa

Abbreviationprevphone
DescriptionCreate an @Preview annotation for a phone in light/dark mode
Shorten FQ Names
1@androidx.compose.ui.tooling.preview.Preview(
2 name = "Phone Night Mode",
3 uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES,
4)
5@androidx.compose.ui.tooling.preview.Preview(
6 name = "Phone Day Mode",
7 uiMode = android.content.res.Configuration.UI_MODE_NIGHT_NO,
8)
Tablet Preview Annotation

This series of @Preview annotation live templates is inspired by William Barbosa

Abbreviationprevtablet
DescriptionCreate an @Preview annotation for a tablet in light/dark mode
Shorten FQ Names
1@androidx.compose.ui.tooling.preview.Preview(
2 name = "Tablet Night Mode",
3 uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES,
4 heightDp = 1080,
5 widthDp = 760,
6)
7@androidx.compose.ui.tooling.preview.Preview(
8 name = "Tablet Day Mode",
9 uiMode = android.content.res.Configuration.UI_MODE_NIGHT_NO,
10 heightDp = 1080,
11 widthDp = 760,
12)
Desktop Preview Annotation

This series of @Preview annotation live templates is inspired by William Barbosa

Abbreviationprevdesktop
DescriptionCreate an @Preview annotation for a desktop in light/dark mode
Shorten FQ Names
1@androidx.compose.ui.tooling.preview.Preview(
2 name = "Desktop Night Mode",
3 uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES,
4 heightDp = 760,
5 widthDp = 1080,
6)
7@androidx.compose.ui.tooling.preview.Preview(
8 name = "Desktop Day Mode",
9 uiMode = android.content.res.Configuration.UI_MODE_NIGHT_NO,
10 heightDp = 760,
11 widthDp = 1080,
12)

What’s next?

Go play with and create some live templates! They are really fun to make and use in day to day development. If you need help with them or want to share what you’ve made reach out on Twitter! I’d love to see them (and add to my collection 😉)!


Header Photo by Tim Arterbury on Unsplash and modified by me.

Special thanks to Adam McNeilly for reviewing and proof reading this article.

Hey! We've got a newsletter!

Your weekly dose of bite sized Android news and events delivered Monday mornings to kick off your week.

Each issue contains TL;DRs of recent articles, a developer tool highlight, interview practice, and a stoic sentiment applied to tech careers.

All with a No-Spam Guarantee.

Read more about it here!

More articles from StoicallyTyped

Adding comments via Utteranc.es

GitHub Issue powered comments are now available on all posts!

March 22nd, 2021 · 1 min read

Newsletter Announcement

Your weekly dose of bite sized Android news and events delivered Monday mornings to kick off your week.

March 19th, 2021 · 1 min read
© 2020–2021 StoicallyTyped
Link to $https://twitter.com/himattmLink to $https://github.com/himattmLink to $https://instagram.com/himattmLink to $https://unsplash.com/@mmckennaLink to $https://medium.com/@himattm