How to use Android Studio File Templates to speed up development.
Tags: android, kotlin, tutorial
Published: 2021-05-06 18:23:04

###Introduction
Android Studio comes with a nifty feature that I use quite often to speed 🚀 up my development process.

Introducing... File Templates🎉.

We have all used this feature probably without realizing it can help us do much more.

An instance where we have all utilized file templates is when we right-click on a package in android studio to create a `Class`, `Enum`, or `Interface`.

Android Studio allows us to modify these file templates and even lets us create our own.

Anytime we create a new `interface` or `class` from the context menu, we are utilizing their respective template files.

Here's an example.

![Creating an Interface](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q23ff3orteqqqvabj1pj.gif)

###The "File and Code Templates" Window.<a name="template-window"></a>

Before we begin editing, let's learn how to access the Templates window. There, we can find all existing templates and also create our own.

Steps:
* Right-click on any file/package
* Navigate to "New"
* Click on "Edit File Templates..."

You should be presented with a window that looks like this.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4p59bbxz93utn15wd3r6.png)
Note: The Android Studio version being used at the time of writing this article, is v4.1.3

###Important information<a name="definitions"></a>

The template language used is [Apache Velocity](https://velocity.apache.org/engine/1.7/user-guide.html).

When working with File Templates in Android Studio, there are a number of helpful predefined variables which we can utilize to simplify creating or editing template contents.

Here are some of these predefined variables and what they do: 

**`${DATE}`**, returns the current system date
**`${TIME}`**, returns the current system time
**`${NAME}`**, defines the name of the new file (class, interface, enum, etc...)
**`${PACKAGE_NAME}`**, returns the name of the target package in which the new class or interface file is created
**`${PROJECT_NAME}`**, returns the name of the current project
**`${USER}`**, returns the login name of the current user.

We will take a closer look at how some of these variables are used later on in this article.

###### Understanding the structure and keywords<a name="old-interface"></a>
Let's take an empty kotlin `interface` class for instance.

This is what it looks like.
```kotlin
package com.samdev.templates

interface MyInterface {
}
```

And below is what the `Kotlin Interface` template looks like.
```kotlin
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME} #end

#parse("File Header.java")
interface ${NAME} {
}
```

You can find the `Kotlin Interface` template by scrolling through the list of available templates in the "File and Code Templates" window.

Now Let's take note of a few things.
1️⃣ The first thing we notice here is how the package name is represented in the template. This is an example of how we use the `${PACKAGE_NAME}` variable mentioned [earlier](#definitions).

2️⃣ The `#if` `#end` block, which basically ensures the existence of a package name before actually printing it out.
This is necessary so when we create a class in the project root folder, the template engine will skip setting the package name, since none exists at that point.

3️⃣ The `${NAME}` variable which we also mentioned [earlier](#definitions) as the variable that is used to define the name of the class. More on this later.

4️⃣ The `#parse` keyword. This script element simply allows us to import a variable or file that contains a template.
Think of this as a "superclass", any templates that exist in the specified file (`File Header.java` in our case) will be applied in the template file that references it. Makes sense?


Let's see the `#parse` script element in action.

The current `File Header` template class is empty, so we are going to place some code in there and see how it affects our existing `interface`.

```
/**
 * @author ${USER}
 * Created ${DATE} at ${TIME}
 */
``` 

Note☝: Any template files we intend to reference with the  `#parse` script element, should be created in the "Includes" section of the "File and Code Templates" window.

![The Includes tab in the Templates window ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fc6jyde5gdqkbt8yj13m.png)


We have already learned what each of the predefined variables `${USER}`, `${DATE}`, and `${TIME}` does (refer to [this guy](#definitions)), so let's just take a look at the gif below to see the effect.

![New interface creation after editing header](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/halcsgxn4fo0wmis52o5.gif)

We end up with something like this.

```kotlin
package com.samdev.templates

/**
 * @author samdev
 * Created 06/05/2021 at 1:14 AM
 */
interface MyInterface {
}
```

You will notice that the section that contained the `#parse` logic, which was blank before, now contains the result of the header template we added.

Note☝: We are not bound by predefined variables when editing templates. We can define our own variables using the [`#set`](https://velocity.apache.org/engine/1.7/user-guide.html#set) element, and we can also create variables whose values will be provided via a prompt displayed by Android Studio.

I will demonstrate this in the next section.


###Creating new templates
To create our own custom templates, we navigate to the "Templates and Code" window by following the steps listed [here](#template-window) and tap the '+' icon at the top left corner.

![New template button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dddibn1u5f7okwmlgi0.png)

We are presented with a view where we are required to name the template and also set the extension.

When writing java templates, we replace the "kt" in the extension field with "java".


After creating our templates, we can find them in the "New" sub-menu, as indicated below.

To use them, all we need to do is click, and follow the prompts.
![find_custom_templates](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r69ukckmzh7aebbiaa2o.png)


###Now, the reason you are here.
For the purpose of this tutorial, we will be creating 2 templates.
1. A Java Singleton template.
2. A Kotlin data access object (Dao) interface template to be used with Room Database.


###The Java Singleton.
Let's take a look at the actual Singleton class below
```java
class MySingleton {

    private static MySingleton instance = null;

    private MySingleton() {
    }

    public static MySingleton getInstance() {
        if (instance == null) {
            synchronized (MySingleton.class) {
                if (instance == null) {
                    instance = new MySingleton();
                }
            }
        }
        return instance;
    }

}
```

Now let's take a look at our singleton template.

```java
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}; #end

#parse("File Header.java")

class ${NAME} {

    private static ${NAME} instance = null;
    
    private ${NAME}() {}
    
    public static ${NAME} getInstance() {
        if (instance == null) {
            synchronized(${NAME}.class) {
                if (instance == null) {
                    instance = new ${NAME}();
                }
            }
        }
        return instance;
    }
}

```
1️⃣ The first thing we do, just as we have previously indicated, is to set the package name, using the `${PACKAGE_NAME}` variable.

2️⃣ We include any necessary header files using the `#parse` script element.

3️⃣ The [`${NAME}`](#definitions) variable is used here again.


Unlike the other variables like `${PACKAGE_NAME}`, `${DATE}`, etc... the `${NAME}` variable obtains its value from user input.

So how do we set the `${NAME}`? The IDE handles that for us, it will display a prompt requesting the Filename.

Let's see how it works in the gif below.
![Java singleton](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7x0ce58lf7f822tn6gr.gif)

After we selected our newly created template named `Java Singleton`, we received a prompt, requesting that we enter the "File name". Whatever value we enter in the dialog becomes the value for `${NAME}`.

That's it! We have successfully created a java singleton template. Whenever we require a java singleton in our current/future projects, all we need to do is select the template, provide a name, and voila! 


###The Dao Interface class.
When working with Room, we interact with the stored data by defining data access objects. The DAOs include methods that offer abstract access to your app's database.

Eg: If we have 3 tables/entities, a `User` table, `Class` table, and a `Lesson` table, we are required to create a Dao class for each table so we can access the data in those tables.

As the number of tables increases, the number of Dao interfaces you have to create also increases.
 
In order to make life a little bit easier for us, we can create a Dao Template file, which will be used anytime we need to create new Dao Interfaces. 

Readers who can not familiar with Room and Dao interfaces can refer to this [link](https://developer.android.com/training/data-storage/room/accessing-data) for clarification.

######Code Sample
Let's look at a  Dao interface sample for a User entity.

```kotlin
＠Dao
interface UserDao {
    ＠Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(users: List<User>)

    ＠Query("SELECT * FROM user")
    fun getAll(): LiveData<List<User>>

    ＠Query("SELECT * FROM user WHERE id = :id")
    fun getById(id: Long) : LiveData<User>

    ＠Delete
    fun delete(User user)
}
``` 

######Template
Now let's look at our Dao template

```kotlin
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME} #end

#parse("File Header.java")

import androidx.lifecycle.LiveData
import androidx.room.*

＠Dao
interface ${NAME} {

    ＠Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(users: List<${Entity_Class}>)
    
    ＠Query("SELECT * FROM ${Table_Name}")
    fun getAll() : LiveData<List<${Entity_Class}>>
    
    ＠Query("SELECT * FROM ${Table_Name} WHERE id = :id")
    fun getById(id: Long) : LiveData<${Entity_Class}>
    
    ＠Delete
    fun delete(entity: ${Entity_Class})
    
}
```

We have introduced a few new concepts.

1️⃣ Class imports. You can import and use any existing classes when creating templates as well. 

2️⃣ Custom variables. You will notice that in this template, we are dealing with multiple custom variables, `${Entity_Class}` to define our entity data type and `${Table_Name}` to define our "table_name"

Syntax to create a custom variable is `${Variable_Name}`

The variables get their values the same way the `${NAME}` predefined variable gets its value, via the prompt.

Let's see them in action in the gif below.
![Dao](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkev8a9tpegc6shf7r74.gif)

###Conclusion
Template classes are not that different from your regular java/kotlin classes, so there's so much you can do with them.

You the next time you need to create a class but already have the template.👇

![goteem](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hec8fwym6tpygsawffmj.gif)

[Here](https://gist.github.com/WilderMinds/d2a7084900c378e525576fb3c748bd2b) are a few more templates you can take a look at to better understand how they work the extent to which they can be used.

If you have questions, please leave them in the comments section and I'd do my best to address them!