去Android Studio的目录/Applications/Android Studio.app/Contents/plugins/android/lib/templates/activities
或是右击应用程序 Android Studio的图标右击显示包内容
里面有很多模板文件夹,要做啥模板,复制个EmptyActivity重命名之后直接在那个基础上改好了。
打开模板文件里面看到
1、先看看template.xml
<?xml version="1.0"?>
<template
format="5"
revision="1"
name="MVPArms 全家桶"
minApi="9"
minBuildApi="15"
description="一键创建 MVPArms 单个页面所需要的全部组件, JessYan 将这个高度可配置的模版献给强大的 MVPArms,使用详情请见 README">
<category value="Activity" />
<formfactor value="Mobile" />
<parameter
id="pageName"
name="Page Name"
type="string"
constraints="unique|nonempty"
default="Main"
help="请填写页面名,如填写 Main,会自动生成 MainActivity, MainPresenter 等文件" />
<parameter
id="packageName"
name="Root Package Name"
type="string"
constraints="package"
default="com.mycompany.myapp"
help="请填写你的项目包名,请认真核实此包名是否是正确的项目包名,不能包含子包,正确的格式如:me.jessyan.arms"
/>
<parameter
id="needActivity"
name="Generate Activity"
type="boolean"
default="true"
help="是否需要生成 Activity ? 不勾选则不生成" />
<parameter
id="activityLayoutName"
name="Activity Layout Name"
type="string"
constraints="layout|nonempty"
suggest="${activityToLayout(pageName)}"
default="activity_main"
visibility="needActivity"
help="Activity 创建之前需要填写 Activity 的布局名,若布局已创建就直接填写此布局名,若还没创建此布局,请勾选下面的单选框" />
<parameter
id="generateActivityLayout"
name="Generate Activity Layout"
type="boolean"
default="true"
visibility="needActivity"
help="是否需要给 Activity 生成布局? 若勾选,则使用上面的布局名给此 Activity 创建默认的布局" />
<parameter
id="ativityPackageName"
name="Ativity Package Name"
type="string"
constraints="package"
suggest="${packageName}.mvp.ui.activity"
visibility="needActivity"
help="Activity 将被输出到此包下,请认真核实此包名是否是你需要输出的目标包名"
/>
<parameter
id="needFragment"
name="Generate Fragment"
type="boolean"
default="false"
help="是否需要生成 Fragment ? 不勾选则不生成" />
<parameter
id="fragmentLayoutName"
name="Fragment Layout Name"
type="string"
constraints="layout|nonempty"
suggest="fragment_${classToResource(pageName)}"
default="fragment_main"
visibility="needFragment"
help="Fragment 创建之前需要填写 Fragment 的布局名,若布局已创建就直接填写此布局名,若还没创建此布局,请勾选下面的单选框" />
<parameter
id="generateFragmentLayout"
name="Generate Fragment Layout"
type="boolean"
default="true"
visibility="needFragment"
help="是否需要给 Fragment 生成布局? 若勾选,则使用上面的布局名给此 Fragment 创建默认的布局" />
<parameter
id="fragmentPackageName"
name="Fragment Package Name"
type="string"
constraints="package"
suggest="${packageName}.mvp.ui.fragment"
visibility="needFragment"
help="Fragment 将被输出到此包下,请认真核实此包名是否是你需要输出的目标包名"
/>
<parameter
id="needContract"
name="Generate Contract"
type="boolean"
default="true"
help="是否需要生成 Contract ? 不勾选则不生成" />
<parameter
id="contractPackageName"
name="Contract Package Name"
type="string"
constraints="package"
suggest="${packageName}.mvp.contract"
visibility="needContract"
help="Contract 将被输出到此包下,请认真核实此包名是否是你需要输出的目标包名"
/>
<parameter
id="needPresenter"
name="Generate Presenter"
type="boolean"
default="true"
help="是否需要生成 Presenter ? 不勾选则不生成" />
<parameter
id="presenterPackageName"
name="Presenter Package Name"
type="string"
constraints="package"
suggest="${packageName}.mvp.presenter"
visibility="needPresenter"
help="Presenter 将被输出到此包下,请认真核实此包名是否是你需要输出的目标包名"
/>
<parameter
id="needModel"
name="Generate Model"
type="boolean"
default="true"
help="是否需要生成 Model ? 不勾选则不生成" />
<parameter
id="modelPackageName"
name="Model Package Name"
type="string"
constraints="package"
suggest="${packageName}.mvp.model"
visibility="needModel"
help="Model 将被输出到此包下,请认真核实此包名是否是你需要输出的目标包名"
/>
<parameter
id="needDagger"
name="Generate Dagger (Moudle And Component)"
type="boolean"
default="true"
help="是否需要生成 Dagger 组件? 不勾选则不生成" />
<parameter
id="componentPackageName"
name="Component Package Name"
type="string"
constraints="package"
suggest="${packageName}.di.component"
visibility="needDagger"
help="Component 将被输出到此包下,请认真核实此包名是否是你需要输出的目标包名"
/>
<parameter
id="moudlePackageName"
name="Moudle Package Name"
type="string"
constraints="package"
suggest="${packageName}.di.module"
visibility="needDagger"
help="Moudle 将被输出到此包下,请认真核实此包名是否是你需要输出的目标包名"
/>
<!-- 128x128 thumbnails relative to template.xml -->
<thumbs>
<!-- default thumbnail is required -->
<thumb>template_blank_activity.png</thumb>
</thumbs>
<globals file="globals.xml.ftl" />
<execute file="recipe.xml.ftl" />
</template>
- id :唯一标识,最终通过该属性的值,获取用户输入值(文本框内容,是否选中)
- name:界面上的类似label的提示语
- type : 输入值类型
- constraints:填写值的约束
- suggest:建议值,比如填写ActivityName的时候,会给出一个布局文件的建议值。
- default:默认值
- help:底部显示的提升语
3、看看recipe.xml.ftl
<?xml version="1.0"?>
<recipe>
<#if needActivity>
<merge from="root/AndroidManifest.xml.ftl"
to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
</#if>
<#if needActivity && generateActivityLayout>
<instantiate from="root/res/layout/simple.xml.ftl"
to="${escapeXmlAttribute(resOut)}/layout/${activityLayoutName}.xml" />
</#if>
<#if needFragment && generateFragmentLayout>
<instantiate from="root/res/layout/simple.xml.ftl"
to="${escapeXmlAttribute(resOut)}/layout/${fragmentLayoutName}.xml" />
</#if>
<#if needActivity>
<instantiate from="root/src/app_package/ArmsActivity.java.ftl"
to="${projectOut}/src/main/java/${slashedPackageName(ativityPackageName)}/${pageName}Activity.java" />
<open file="${projectOut}/src/main/java/${slashedPackageName(ativityPackageName)}/${pageName}Activity.java" />
</#if>
<#if needFragment>
<instantiate from="root/src/app_package/ArmsFragment.java.ftl"
to="${projectOut}/src/main/java/${slashedPackageName(fragmentPackageName)}/${pageName}Fragment.java" />
<open file="${projectOut}/src/main/java/${slashedPackageName(fragmentPackageName)}/${pageName}Fragment.java" />
</#if>
<#if needContract>
<instantiate from="root/src/app_package/ArmsContract.java.ftl"
to="${projectOut}/src/main/java/${slashedPackageName(contractPackageName)}/${pageName}Contract.java" />
</#if>
<#if needPresenter>
<instantiate from="root/src/app_package/ArmsPresenter.java.ftl"
to="${projectOut}/src/main/java/${slashedPackageName(presenterPackageName)}/${pageName}Presenter.java" />
<open file="${projectOut}/src/main/java/${slashedPackageName(presenterPackageName)}/${pageName}Presenter.java" />
</#if>
<#if needModel>
<instantiate from="root/src/app_package/ArmsModel.java.ftl"
to="${projectOut}/src/main/java/${slashedPackageName(modelPackageName)}/${pageName}Model.java" />
</#if>
<#if needDagger>
<instantiate from="root/src/app_package/ArmsComponent.java.ftl"
to="${projectOut}/src/main/java/${slashedPackageName(componentPackageName)}/${pageName}Component.java" />
<instantiate from="root/src/app_package/ArmsModule.java.ftl"
to="${projectOut}/src/main/java/${slashedPackageName(moudlePackageName)}/${pageName}Module.java" />
</#if>
</recipe>
- copy :从root中copy文件到我们的目标目录,比如我们的模板Activity需要使用一些图标,那么可能就需要使用copy标签将这些图标拷贝到我们的项目对应文件夹。
- merge : 合并的意思,比如将我们使用到的strings.xml合并到我们的项目的stirngs.xml中
- instantiate : 和copy类似,但是可以看到上例试将ftl->java文件的,也就是说中间会通过一个步骤,将ftl中的变量都换成对应的值,那么完整的流程是
ftl->freemarker process -> java
。 - open:在代码生成后,打开指定的文件,比如我们新建一个Activity后,默认就会将该Activity打开。
注意一下root/src/app_package这个路径
然后各自打开看看里面的内容
AndroidManifest
res<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application> <activity android:name="${ativityPackageName}.${activityClass}" > </activity> </application> </manifest>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> </LinearLayout>
ArmsModel.java.ftl
package ${modelPackageName}; import android.app.Application; import com.google.gson.Gson; import com.jess.arms.integration.IRepositoryManager; import com.jess.arms.mvp.BaseModel; import com.jess.arms.di.scope.ActivityScope; import javax.inject.Inject; import ${contractPackageName}.${pageName}Contract; @ActivityScope public class ${pageName}Model extends BaseModel implements ${pageName}Contract.Model{ private Gson mGson; private Application mApplication; @Inject public ${pageName}Model(IRepositoryManager repositoryManager, Gson gson, Application application) { super(repositoryManager); this.mGson = gson; this.mApplication = application; } @Override public void onDestroy() { super.onDestroy(); this.mGson = null; this.mApplication = null; } }