Hello again dear Android developers. I hope that you’ve read my blog post about basic Android templates. If you haven’t, please do so because it will help you understand today’s topic. In this blog post, I will show you how to make Android MVP group templates for Android Studio. This will save you a lot of time and make Android programming more exciting.

Why should I use MVP templates?

Manually writing activity or fragment MVP structure will take you about 10-20 minutes, but if you use templates it’s a matter of seconds.

What do I need for MVP templates?

You need Dagger 2 and some will power.

Android group templates basics

This is an example of Group templates files structure:

and files are located in (MacOs) ANDROID_STUDIO_LOCATION/plugins/android/lib/templates/activities

The idea is to create variables which will be used for package structure generating and class generating.

Variables are declared in template.xml

template.xml should have <template> root tag, and variables should be described by <parameter> tags.

<parameter
id="folderName"
name="Folder Name"
type="string"
constraints="class|unique|nonempty"
default="demo"
help="Activity root folder" />

Variables should have:

id – this is the variable name which will be used for substitution

name – this will be shown in creational templates pop-up

type – variable input type

constraints – describes entry property

help – used for input variable description

also, variables can be prefilled if other entries are filled. This is done with the “suggest” attribute.

The structure is generated with recipe.xml.ftl

Recipe has root tag <recipe> and structure is declared by <instantiate> tags

   Instantiate from="src/app_package/classes/Activity.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/view/${activityClass}.java"    

recipe should have:
from – used for finding class ftl file. This file will be used for class generating later.
to – used for creating folder structure and class name. Class will be created inside folder structure.
The class template is defined by xxx.ftl file and class template making logic is already explained in previous tutorial.

Let’s make a MVP template step by step

I assume that you know how to use and setup Dagger 2, so I will skip this part.

Step 1

Navigate to ANDROID_STUDIO_LOCATION/plugins/android/lib/templates/activities

Step 2

Create files structure like in the picture below.

3. Creating files

activity_layout_recipe.xml.ftl
<recipe>
<instantiate from="src/app_package/layout/activity_layout.xml.ftl"
to="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />
</recipe>

This file is used for making activity layout.

globals.xml.ftl
<?xml version="1.0"?>
<globals>
<global id="hasNoActionBar" type="boolean" value="false" />
<global id="parentActivityClass" value="" />
<global id="simpleLayoutName" value="${layoutName}" />
<global id="excludeMenu" type="boolean" value="true" />
<global id="generateActivityTitle" type="boolean" value="false" />
<global id="relativePackage" type="string" value=".${folderName}.activity.view"/>
<#include "../common/common_globals.xml.ftl" />
</globals>

This file is used for creating global variables. Global variables are used for updating the manifest file when new MVP activity is created.

recipe.xml.ftl
<?xml version="1.0"?>
<recipe>
<#include "../common/recipe_manifest.xml.ftl" />
<#include "activity_layout_recipe.xml.ftl" />
<instantiate from="src/app_package/classes/Activity.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/view/${activityClass}.java" />
<instantiate from="src/app_package/classes/View.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/view/${viewClass}.java" />
<instantiate from="src/app_package/classes/Component.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/${componentClass}.java" />
<instantiate from="src/app_package/classes/Module.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/${moduleClass}.java" />
<instantiate from="src/app_package/classes/PresenterImpl.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/presenter/${presenterClass}Impl.java" />
<instantiate from="src/app_package/classes/Presenter.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/presenter/${presenterClass}.java" />
<instantiate from="src/app_package/classes/InteractorImpl.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/interactor/${interactorClass}Impl.java" />
<instantiate from="src/app_package/classes/Interactor.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${folderName}/activity/interactor/${interactorClass}.java" />
</recipe>

Recipe is a key component that is used for generating packages and classes.

template.xml
<?xml version="1.0"?>
<template
format="2"
revision="2"
name="MVP Activity"
minApi="7"
minBuildApi="14"
description="Generate MVP structure, classes and interfaces">
<category value="MVP blog" />
<formfactor value="Mobile" />
<parameter
id="folderName"
name="Folder Name"
type="string"
constraints="class|unique|nonempty"
default="demo"
help="Activity root folder" />
<parameter
id="isLauncher"
name="Launcher Activity"
type="boolean"
default="false"/>
<parameter
id="activityClass"
name="Activity Name"
type="string"
constraints="class|unique|nonempty"
suggest="${layoutToActivity(folderName)}"
default="MainActivity"
help="Activity name" />
<parameter
id="layoutName"
name="Layout Name"
type="string"
constraints="layout|unique|nonempty"
suggest="${activityToLayout(activityClass)}"
default="activity_main"
help="Activity layout name" />
<parameter
id="packageName"
name="Package name"
type="string"
constraints="package.${folderName}"
default="com.test.test"
help="Enter package name" />
<parameter
id="applicationpackage"
name="Application package name"
type="string"
constraints="package"
default="com.test.test" />    
<parameter
id="viewClass"
name="View Name"
type="string"
constraints="class|nonempty|unique"
default="MainView"
suggest="${underscoreToCamelCase(activityClass)}View"
help="View interface name" />
<parameter
id="presenterClass"
name="Presenter Name"
type="string"
constraints="class|nonempty|unique"
default="MainPresenter"
suggest="${underscoreToCamelCase(activityClass)}Presenter"
help="Presenter name" />   
<parameter
id="interactorClass"
name="Interactor Name"
type="string"
constraints="class|nonempty|unique"
default="MainInteractor"
suggest="${underscoreToCamelCase(activityClass)}Interactor"
help="Interactor name" />  
<parameter
id="componentClass"
name="Component Name"
type="string"
constraints="class|nonempty|unique"
default="MainComponent"
suggest="${underscoreToCamelCase(activityClass)}Component"
help="Component name" />
<parameter
id="moduleClass"
name="Module Name"
type="string"
constraints="class|nonempty|unique"
default="MainModule"
suggest="${underscoreToCamelCase(activityClass)}Module"
help="Module name" />  	 
<globals file="globals.xml.ftl" />
<execute file="recipe.xml.ftl" />
</template>

This file is used for variable declaration, autosuggest is also used.
Files in app_package are single templates which you can find on GitHub repo.
These templates will generate all classes declared in recipe.xml.ftl file, and it will use variables declared in template.xml file.

How to use MVP templates?

Press right mouse button on the package where you want to generate activity (keep in mind that group templates will create the MVP activity package automatically), then select news/MVP blog/MVP Activity. After that pop up will be displayed.

Enter Folder name and all other fields should be prefilled (except Application package name), then hit finish and all classes and interfaces for MVP would be generated.

Conclusion

Android MVP templates are simple for made and save a lot of time. Now you can made fragment MVP and save even more time. This blog post is last blog post of templates series, I hope that you will start using templates, and start saving time.