Page 2 of 2
Recipe.xml.ftl
The Recipe file does all of the work setting up the project, but it does most of this by copying and expanding directories which exist in the template root directory.
One key command that you are likely to use is copy, which copies a directory and all its subdirectories from the template root to the project. The command instantiate does the same job as copy, but it expands any FreeMarker tags within the files. The final command is merge, which as you can guess merges the content of a source file in the template root with a project file.
The Recipe file starts out by loading compatibility libraries if they are needed:
<?xml version="1.0"?> <recipe> <#if appCompat?has_content> <dependency mavenUrl="com.android.support:appcompat-v7:+"/> </#if> <#if !appCompat?has_content && hasViewPager?has_content> <dependency mavenUrl="com.android.support:support-v13:+"/> </#if> <#if !appCompat?has_content > <dependency mavenUrl="com.android.support:support-v4:+"/> </#if>
You might as well leave these lines in your own Recipe file.
Next we need to create the manifest:
<merge from="AndroidManifest.xml.ftl" to="${escapeXmlAttribute(manifestOut)}/ AndroidManifest.xml" />
The template manifest is stored in the root:
<manifest xmlns:android= "http://schemas.android.com/apk/res/android" > <application> <activity android:name= "${packageName}.${activityClass}" <#if isNewProject> android:label="@string/app_name" <#else> android:label="@string/title_${ activityToLayout(activityClass)}" </#if> <#if buildApi gte 16 && parentActivityClass != ""> android:parentActivityName= "${parentActivityClass}" </#if> > <#if parentActivityClass != ""> <meta-data android:name= "android.support.PARENT_ACTIVITY" android:value="${parentActivityClass}" /> </#if> <#if isLauncher> <intent-filter> <action android:name= "android.intent.action.MAIN" /> <category android:name= "android.intent.category.LAUNCHER" /> </intent-filter> </#if> </activity> </application> </manifest>
When this file is processed it is merged with any existing manifest file in such a way that only the new lines are added. What this means is that when the same template is used to create a new activity within an existing project only the new definition of the activity is added to the existing manifest.
Next we have to merge some resource files:
<merge from="res/values/strings.xml.ftl" to="${escapeXmlAttribute(resOut)}/ values/strings.xml" /> <merge from="res/values/dimens.xml.ftl" to="${escapeXmlAttribute(resOut)}/ values/dimens.xml" /> <merge from="res/values-w820dp/dimens.xml" to="${escapeXmlAttribute(resOut)}/ values-w820dp/dimens.xml" />
As before, the values are merged with any existing files so there is no duplication of definitions.
The strings.xml file is where we put the "Hello world" message:
<resources> <#if !isNewProject> <string name= "title_${activityToLayout(activityClass)}"> ${escapeXmlString(activityTitle)}</string> </#if> <string name="hello_world">Hello world!</string> </resources>
The dimens file just contains some basic layout properties;
<resources> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name= "activity_horizontal_margin">16dp</dimen> <dimen name= "activity_vertical_margin">16dp</dimen> </resources>
If you want to define additional string resources or layout parameters simply add them to the appropriate file.
Our final task is to create the Java source and the xml layout files and this is just a matter of copying and expanding two template files:
<instantiate from= "res/layout/simpleactivity.xml.ftl" to="${escapeXmlAttribute(resOut)}/ layout/${layoutName}.xml" /> <instantiate from= "src/app_package/SimpleActivity.java.ftl" to="${escapeXmlAttribute(srcOut)}/ ${activityClass}.java" />
The layout file template simpleactivity.xml is very simple:
<RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft= "@dimen/activity_horizontal_margin" android:paddingRight= "@dimen/activity_horizontal_margin" android:paddingTop= "@dimen/activity_vertical_margin" android:paddingBottom= "@dimen/activity_vertical_margin" tools:context="${packageName}.${activityClass}">
<TextView android:text="@string/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
You can modify RelativeLayout to be any sort of container you want and you can remove the "hello world" message if you find it gets in the way.
The Java template is:
package ${packageName};
import <#if appCompat?has_content> android.support.v7.app.ActionBarActivity <#else>android.app.Activity </#if>; import android. <#if appCompat?has_content>support.v7.</#if> app.ActionBar; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.os.Build;
public class ${activityClass} extends Activity {
@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.${layoutName}); } }
As before, you can modify this to include features you might want, but this the very minimum.
Finally if you want to open some files in the editor ready for the programmer to start work you can:
<open file= "${escapeXmlAttribute(srcOut)}/ ${activityClass}.java" />
</recipe>
This opens the jave souce code ready to work.
This ends the recipe file and the entire template.
Where Next
It would be wise not to spend too much time and effort on hand crafted templates as Android Studio is still changing, but you can see that simple templates are easy enough. If you study the documentation for FreeMarker and use the existing templates as examples, you should be able to cope until there is full documentation.
The template presented here can be downloaded from the CodeBin . Note you have to register with I Programmer to access this.
It also used in our ongoing series, Adventures with Android Studio .
Related Articles:
Android ADT Template Format Document
Android Adventures With Android Studio
Getting Started With Android Studio
The Activity And The UI
Building The UI and a Calculator App
Lifecycle and State
Basic Controls And Events
Spinners
Pickers
Comments
Make a Comment or View Existing Comments Using Disqus
or email your comment to: comments@i-programmer.info
To be informed about new articles on I Programmer, subscribe to the RSS feed , follow us on Google+ , Twitter, Linkedin or Facebook or sign up for our weekly newsletter .