Android Studio自定义模板

前言

在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" />

    
    <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将会在下面提到。


globals.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

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.xml.ftl


<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:合并文件

你可能感兴趣的:(工具使用)