Last Updated: October 03, 2020
·
34.48K
· swampmobile

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>

1 Response
Add your response

How to add lint options in build.gradle ?

over 1 year ago ·
  NODES
Community 1
Idea 2
idea 2
iOS 2
Javascript 4
os 7
todo 1