Reputation: 68
I was trying to create project templates to optimize my time, I found many answers about it but don't work on newest versions of Android Studio. I tried to copy an existing project template and worked but only if I use the same name of the main project template.
What I need is only create a new project template and show in the wizard screen like in this picture:
I created a copy of BasicActivity folder that I found at this path {AndroidStudio Program Files folder}\plugins\android\lib\templates\activities and changed template.xml file of my copied template, changing the name of template and category value.
But after restart the Android Studio, my new project wasn't showed, what I need to do to show new project templates?
I was reading the source code of android plugin in IntelliJ repository and my template is at the correct format to show on the wizard.
My example: template.xml
<template
revision="1"
name="My template"
minApi="9"
minBuildApi="14"
description="Example template">
<parameter
id="className"
name="Feature name"
type="string"
constraints="class|nonempty|unique"
default="ExampleFeature"
help="Feature name (omit 'fragment' suffix)" />
<category value="Activity"/>
<!-- 128x128 thumbnails relative to template.xml -->
<thumbs>
<!-- default thumbnail is required -->
<thumb>template_basic_activity.png</thumb>
</thumbs>
<globals file="globals.xml.ftl"/>
<execute file="recipe.xml.ftl"/>
</template>
globals.xml.ftl
<?xml version="1.0"?>
<globals>
<global id="resOut" value="${resDir}" />
<global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
</globals>
recipe.xml.ftl
<!--?xml version="1.0"?-->
<recipe>
<instantiate from="root/res/layout/fragment_demo.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/fragment_${classToResource(className)}.xml"></instantiate>
<open file="${escapeXmlAttribute(resOut)}/layout/fragment_${classToResource(className)}.xml"></open>
<instantiate from="root/src/app_package/DemoView.java.ftl" to="${escapeXmlAttribute(srcOut)}/${className}View.java"></instantiate>
<open file="${escapeXmlAttribute(srcOut)}/${className}View.java"></open>
<instantiate from="root/src/app_package/DemoPresenter.java.ftl" to="${escapeXmlAttribute(srcOut)}/${className}Presenter.java"></instantiate>
<open file="${escapeXmlAttribute(srcOut)}/${className}Presenter.java"></open>
<instantiate from="root/src/app_package/DemoFragment.java.ftl" to="${escapeXmlAttribute(srcOut)}/${className}Fragment.java"></instantiate>
<open file="${escapeXmlAttribute(srcOut)}/${className}Fragment.java"></open>
</recipe>
Analyzing the IntelliJ android plugin, I found this point that can be where the IDE searches user templates directory, I have put a copy of my template at this place too and don't worked.
private static List<File> getUserDefinedTemplateRootFolders() {
List<File> folders = new ArrayList<>();
String homeFolder = AndroidLocation.getFolderWithoutWrites();
if (homeFolder != null) {
// Look in $userhome/.android/templates
File templatesFolder = new File(homeFolder, FD_TEMPLATES);
if (templatesFolder.isDirectory()) {
Collections.addAll(folders, templatesFolder);
}
}
return folders;
}
And at this point:
@GuardedBy("CATEGORY_TABLE_LOCK")
private void addTemplateToTable(@NotNull File newTemplate, boolean userDefinedTemplate) {
TemplateMetadata newMetadata = getTemplateMetadata(newTemplate, userDefinedTemplate);
if (newMetadata != null) {
String title = newMetadata.getTitle();
if (title == null || (newMetadata.getCategory() == null &&
myCategoryTable.columnKeySet().contains(title) &&
myCategoryTable.get(CATEGORY_OTHER, title) == null)) {
// If this template is uncategorized, and we already have a template of this name that has a category,
// that is NOT "Other," then ignore this new template since it's undoubtedly older.
return;
}
String category = newMetadata.getCategory() != null ? newMetadata.getCategory() : CATEGORY_OTHER;
File existingTemplate = myCategoryTable.get(category, title);
if (existingTemplate == null || compareTemplates(existingTemplate, newTemplate) > 0) {
myCategoryTable.put(category, title, newTemplate);
}
}
}
Upvotes: 4
Views: 5198
Reputation: 727
That's correct. In Android Studio 3.6 and 4.0 beta5 it is not possible to add new activity templates to "Mobile" form-factor in New Project Wizard, because the list of template titles is hard-coded in the source code. But it is possible to add templates to the other form-factors.
Note that even for mobile form-factor, the new activity template can be used after the project has been created (File > New > Activity > "New Template Title here"
)
Starting from Android Studio 4.0 the Template API will (hopefully) be opened in the form of extension point (see https://issuetracker.google.com/issues/154531807)
In the IntelliJ IDEA it is possible to create a template from existing project.
UPD: Templates provider API is now available in Android Studio 4.1. EP name is com.android.tools.idea.wizard.template.wizardTemplateProvider
(https://android.googlesource.com/platform/tools/base/+/refs/heads/studio-master-dev/wizard/template-plugin/src/com/android/tools/idea/wizard/template/WizardTemplateProvider.kt)
Upvotes: 9