Android Studio自定义模板

来源:互联网 发布:wps数据不能求和 编辑:程序博客网 时间:2024/06/05 14:17
### 前言在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 - SimpleActivity.java.ftl - SimpleActivity.kt.ftl - globals.xml.ftl - recipe.xml.ftl - template.xml - templat_black_activity.png其中root目录下是模板ftl文件globals.xml.ftl是全局参数配置文件recipe.xml.ftl是控制文件创建和修改template.xml和templat_black_activity.png是创建时的UI界面控制———-### template.xml
<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" />    <!-- 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>

上面就是template.xml和对应的创建UI示图。


template标签主要显示一些名称、描述和一些需要的版本信息,这里我写的测试模板名称为TheMVP Activity。

< category value=”Activity” /> 说明该标签放在Activity目录下,如果设置为Fragment则放在Fragment目录先下。


parameter标签就是主要的创建item的标签了


    <parameter        id="packageName"        name="Package name"        type="string"        constraints="package"        default="com.mycompany.myapp" />

这个是默认的选择包名的parameter

    <thumbs>        <thumb>template_blank_activity.png</thumb>    </thumbs>    <globals file="globals.xml.ftl" />    <execute file="recipe.xml.ftl" />

这三个是配置外部关联文件,template_blank_activity.png就显示在UI示图左边,globals.xml.ftl和recipe.xml.ftl将会在下面提到。


globals.xml.ftl

<?xml version="1.0"?><globals><#if isCreateDelegate>    <global id="superClass" type="string" value="ActivityPresenter&lt;${delegateClass}&gt;" /><#else>    <global id="superClass" type="string" value="ActivityPresenter&lt;${linkedDelegate}&gt;" /></#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

root目录下方的是一些作为模板的activity、layout、fragment文件

package ${packageName}.activityimport android.app.Activityimport android.content.Intentimport android.os.Bundleimport ${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.xml.ftl

<?xml version="1.0"?><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是一个管理创建的文件,主要用到的操作标签有:

  • copy:从root文件夹复制文件到目标文件夹
  • instantiate:从root中将对应的ftl文件经处理后转为目标文件
  • open:打开目标文件
  • merge:合并文件