在Android Studio如果我们需要新建一个Activity一般都会new一个Empty Activity。然而新建出来的结果往往还不是我们需要的,还需要进行一些修改。比如说Activity默认是继承AppCompatActivity而一般我都习惯写一个统一的父类来继承,并且在Activity中做一些初始化的操作,如果使用MVP模式还需要新建一个Presenter类。对于这些需求我一直都是在创建完后再进行修改和新建,直到我我看到了Android Studio的自定义模板。
首先我们找到AS默认模板的存放路径
AS3.0\android-studio\plugins\android\lib\templates
其中我们平时常用的模板就放在activity和other这两个文件夹下。
先以最简单的EmptyActivity为例,他的结构目录是
其中root目录下是模板ftl文件
globals.xml.ftl是全局参数配置文件
recipe.xml.ftl是控制文件创建和修改
template.xml和templat_black_activity.png是创建时的UI界面控制
<template
format="5"
revision="5"
name="TheMVP Activity"
minApi="9"
minBuildApi="14"
description="Creates a new empty activity with TheMVP">
<category value="Activity" />
<formfactor value="Mobile" />
<parameter
id="activityClass"
name="Activity Name"
type="string"
constraints="class|unique|nonempty"
suggest="${layoutToActivity(layoutName)}"
default="MainActivity"
help="The name of the activity class to create" />
<parameter
id="delegateClass"
name="Delegate Name"
type="string"
constraints="class|unique|nonempty"
default="MainDelegate"
visibility="isCreateDelegate"
help="The name of the delegate class to create" />
<parameter
id="layoutName"
name="Layout Name"
type="string"
constraints="layout|unique|nonempty"
suggest="${activityToLayout(activityClass)}"
default="activity_main"
visibility="isCreateDelegate"
help="The name of the layout to create for the activity" />
<parameter
id="linkedDelegate"
name="Linked Delegate"
type="string"
constraints="nonempty"
default="AppDelegate"
visibility="!isCreateDelegate"
help="Chose exists delegate"/>
<parameter
id="isCreateDelegate"
name="Create Delegate"
type="boolean"
default="true"
help="If false, this delegate and layout will not be created" />
<parameter
id="packageName"
name="Package name"
type="string"
constraints="package"
default="com.mycompany.myapp" />
<thumbs>
<thumb>template_blank_activity.pngthumb>
thumbs>
<globals file="globals.xml.ftl" />
<execute file="recipe.xml.ftl" />
template>
上面就是template.xml和对应的创建UI示图。
template标签主要显示一些名称、描述和一些需要的版本信息,这里我写的测试模板名称为TheMVP Activity。
< category value=”Activity” /> 说明该标签放在Activity目录下,如果设置为Fragment则放在Fragment目录先下。
parameter标签就是主要的创建item的标签了
"packageName"
name="Package name"
type="string"
constraints="package"
default="com.mycompany.myapp" />
这个是默认的选择包名的parameter
<thumbs>
<thumb>template_blank_activity.pngthumb>
thumbs>
<globals file="globals.xml.ftl" />
<execute file="recipe.xml.ftl" />
这三个是配置外部关联文件,template_blank_activity.png就显示在UI示图左边,globals.xml.ftl和recipe.xml.ftl将会在下面提到。
xml version="1.0"?>
<globals>
<#if isCreateDelegate>
<global id="superClass" type="string" value="ActivityPresenter<${delegateClass}>" />
<#else>
<global id="superClass" type="string" value="ActivityPresenter<${linkedDelegate}>" />
#if>
<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" />
<#include "../common/common_globals.xml.ftl" />
globals>
globals.xml.ftl中的内容比较简单,就是一些全局使用的值。这里有一个简单的逻辑标签
<#if Boolean>
<#else>
#if>
root目录下方的是一些作为模板的activity、layout、fragment文件
package ${packageName}.activity
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import ${applicationPackage}.base.ActivityPresenter
<#if isCreateDelegate>
import ${packageName}.delegate.${delegateClass}
<#else>
import ${packageName}.delegate.${linkedDelegate}
#if>
class ${activityClass} : ${superClass}() {
<#if isCreateDelegate>
override fun instanceDelegate(): ${delegateClass} {
return ${delegateClass}()
}
<#else>
override fun instanceDelegate(): ${linkedDelegate} {
return ${linkedDelegate}()
}
#if>
companion object {
fun start(activity: Activity) {
val intent=Intent(activity,${activityClass}::class.java)
start(activity,intent)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
写法也比较简单,与正常的代码一样,只是在一些位置将之前template.xml和globals.xml.ftl中输入和定义的值用${id}代替
<recipe>
<#if generateKotlin>
<instantiate from="root/src/app_package/SimpleActivity.kt.ftl"
to="${escapeXmlAttribute(srcOut)}/activity/${activityClass}.kt" />
<open file="${escapeXmlAttribute(srcOut)}/activity/${activityClass}.kt" />
<#if isCreateDelegate>
<instantiate from="root/src/app_package/SimpleDelegate.kt.ftl"
to="${escapeXmlAttribute(srcOut)}/delegate/${delegateClass}.kt" />
<open file="${escapeXmlAttribute(srcOut)}/delegate/${delegateClass}.kt" />
<instantiate from="root/src/app_package/activity_simple.xml.ftl"
to="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />
<open file="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />
#if>
#if>
<merge from="root/AndroidManifest.xml.ftl"
to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
recipe>
recipe是一个管理创建的文件,主要用到的操作标签有: