File Templates in Android Studio
Problem
I decided to create a template for a fragment but where does one do that in Android Studio?
First I pulled up the IDE settings within Android Studio. I located an area that listed various templates. I thought for sure I had found it. I created a new template called "Lifecycle Fragment" and filled it with the desired content. Then I applied the changes and closed the window.
I right clicked my fragments package > new >....nothing had changed. It turned out that what I had created was a generic Java template. I could use it by going to new > java class > drop down to "Lifecycle Fragment". But this clearly was not ideal because it did not hook into the Android area of the templates. Also, what would I do in the future for a template that required layout resources? I wanted to get this right.
Android Templates
After some searching I discovered that the Android templates used in Android Studio are not specific to Android Studio at all. In fact, they aren't even specific to IntelliJ. Rather, these templates hook into ADT and are based on a system called FreeMarker. This is the same template technology that provides templates within Eclipse using the ADT Plugin.
Android Templates Location
You can find all the Android Studio android templates in:
ANDROID_STUDIO_DIR/plugins/android/lib/templates
Android Templates Structure & Format
You can learn how to structure and format templates here:
Android ADT Template Format Document
Template Example
I created a new template called "Lifecycle Fragment" and I placed it in the "other" directory located at the path described above. The content of these files are shown below to get an idea of what a template looks like.
The directory structure is:
FragmentWithLifecycle
./template.xml
./recipe.xml.ftl
./globals.xml.ftl
./temlpate_self_fragment.png
./root/src/app_package/LifecycleFragment.java.ftl
./root/res/layout/fragment_self.xml.ftl
template.xml
<?xml version="1.0"?>
<template
format="4"
revision="1"
name="New Fragment With Lifecycle"
minApi="7"
minBuildApi="8"
description="Creates a new fragment, with hooks for the entire fragment lifecycle and a static initializer.">
<dependency name="android-support-v4" revision="8" />
<category value="Other" />
<parameter
id="className"
name="Fragment Name"
type="string"
constraints="class|unique|nonempty"
default="MyFragment"
help="The name of the fragment class to create" />
<parameter
id="includeLayout"
name="Create layout XML?"
type="boolean"
default="true"
help="Generate a layout XML for the fragment" />
<thumbs>
<thumb>template_self_fragment.png</thumb>
</thumbs>
<globals file="globals.xml.ftl" />
<execute file="recipe.xml.ftl" />
</template>
recipe.xml.ftl
<?xml version="1.0"?>
<recipe>
<dependency mavenUrl="com.android.support:support-v4:+"/>
<#if includeLayout>
<instantiate from="res/layout/fragment_self.xml.ftl"
to="${escapeXmlAttribute(resOut)}/layout/fragment_${classToResource(className)}.xml" />
<open file="${escapeXmlAttribute(resOut)}/layout/fragment_${classToResource(className)}.xml" />
</#if>
<open file="${escapeXmlAttribute(srcOut)}/${className}.java" />
<instantiate from="src/app_package/LifecycleFragment.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${className}.java" />
</recipe>
globals.xml.ftl
<?xml version="1.0"?>
<globals>
<global id="resOut" value="${resDir}" />
<global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
</globals>
template_blank_fragment.png
Copied this from the pre-existing Blank Fragment template directory.
root/src/app_package/LifecycleFragment.java.ftl
package ${packageName};
import <#if appCompat?has_content>android.support.v7.app.ActionBarActivity<#else>android.app.Activity</#if>;
import android.<#if appCompat?has_content>support.v4.</#if>app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ${className} extends Fragment {
//public static final String arg_param1 = "SOMETHING";
public static ${className} newInstance()
{
${className} frag = new ${className}();
// Get arguments pass in, if any
Bundle args = frag.getArguments();
if(args == null)
{
args = new Bundle();
}
// Add parameters to the arguments bundle
//args.putInt(SOME_KEY, someValue);
frag.setArguments(args);
return frag;
}
public ${className}()
{
// TODO
}
//------- Start Fragment Lifecycle -----------
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
<#if includeLayout>
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_${classToResource(className)}, container, false);
<#else>
return super.onCreateView(inflater, container, savedInstanceState);
</#if>
}
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart()
{
super.onStart();
}
@Override
public void onResume()
{
super.onResume();
}
@Override
public void onPause()
{
super.onPause();
}
@Override
public void onStop()
{
super.onStop();
}
@Override
public void onDestroyView()
{
super.onDestroyView();
}
@Override
public void onDestroy()
{
super.onDestroy();
}
@Override
public void onDetach()
{
super.onDetach();
}
//------- End Fragment Lifecycle -------------
}
root/res/layout/fragment_self.xml.ftl
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
</LinearLayout>
Written by Matt
Related protips
1 Response
How to add lint options in build.gradle ?