android studio 模板介绍

AndroidStudio Live File Plugin Template


前言

在日常开发中,适当的使用模板,可以提高开发速度,减少重复敲代码的时间,也避免了细节上的错误。一次编写,,到处使用。强大的模板,还可以帮组新同事快速进入开发状态。也就大大的提高了开发速度。
as内置了三种模板,这里,将简单的介绍下这几个模板

模板 适用范围 备注
live templates 代码块 小巧便捷
file templates 单文件创建 设置简单,使用也不算复杂
plugin templates 多文件创建 功能强大,定义模板比较麻烦

一、live templates

在代码中输入key得到相应提示的模板,一般用于简化一些常用的语句,常规性代码块。
系统内置了很多的模板,可以根据实际习惯修改,也可以添加新的模板。
比如,在方法中,输入sout,敲下enter或者tab就可以输出System.out.println()
as支持设置变量,变量可以使用内置函数自动赋值,也可以手动敲入,

适用范围:代码块
设置入口:settings-->Editor-->Live Templates

二、File templates

在创建文件的时候,as提供了一些模板,如java、Singleton等,在创建后就自动生成模板的代码,一般用于单文件级别的代码模板,大多数人用他的header来修改注释模板吧,其实如果将整个模板代码写进去也是ok,
缺点:只能处理当前文件,
比如,你用这个模板设置了Activity的模板代码,最终还是要跑到manifest去注册这哥activity

适用范围:单文件创建
设置入口:settings-->Editor-->File and Code Templates

三、plugin templates

在创建Activity的时候,你会发现,as会自动将你的activity加入manifest,创建相应的layout.xml,这个模板的强大在于,他可以在创建文件的时候,同时处理多个文件
缺点:定义比较麻烦,而且,每次升级as后,会自动还原模板,需要备份好模板,以便下次copy

使用范围:多文件创建
设置入口:%as安装根目录%\plugins\android\lib\templates\activities

这是本文要重点讲的一块,这个模板在as中只能没有开放设置,只能找到安装目录,将模板放进去

四、深入了解系统内置模板

在activities中,我们能看到需要熟悉的文件名,这就是我们用as创建activity的时候内置的模板。
以EmptyActivity为例,需要用到common,其他的文件夹先忽略.

图片
图片

我们看到,这里是用了ftl,不会的话没关系,这个基本上会一门语言的人都能看懂

1. root

里面放的是代码的模板文件,XXX.java.ftl,XXX.xml.ftl

2. globals.xml.ftl

定义全局变量,引用了common的全局变量

<?xml version="1.0"?>
<globals>
    <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>

3.recipe.xml.ftl

定义了执行文件

recipe.xml.ftl
<?xml version="1.0"?>
<recipe>
    <#include "../common/recipe_manifest.xml.ftl" />

    <#if generateLayout>
        <#include "../common/recipe_simple.xml.ftl" />
        <open file="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />
    </#if>

    <instantiate from="root/src/app_package/SimpleActivity.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/${activityClass}.java" />

    <open file="${escapeXmlAttribute(srcOut)}/${activityClass}.java" />
</recipe>

上面的代码做了三件事

a. 合并manifest

b. 自动生成layout.xml布局文件,并打开

c. 自动生成activity.java代码文件,并打开

合并manifest

common/recipe_manifest.xml.ftl
<recipe folder="root://activities/common">

    <merge from="root/AndroidManifest.xml.ftl"
             to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
    <merge from="root/res/values/manifest_strings.xml.ftl"
             to="${escapeXmlAttribute(resOut)}/values/strings.xml" />

</recipe>
common/root/AndroidManifest.xml.ftl
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >

    <application>
        <activity android:name="${relativePackage}.${activityClass}"
            <#if generateActivityTitle!true>
                <#if isNewProject>
                    android:label="@string/app_name"
                <#else>
                    android:label="@string/title_${activityToLayout(activityClass)}"
                </#if>
            </#if>
            <#if hasNoActionBar>
                android:theme="@style/${themeNameNoActionBar}"
            </#if>
            <#if buildApi gte 16 && parentActivityClass != "">
                android:parentActivityName="${parentActivityClass}"
            </#if>>
            <#if parentActivityClass != "">
                <meta-data android:name="android.support.PARENT_ACTIVITY"
                    android:value="${parentActivityClass}" />
            </#if>
            <#if isLauncher && !(isLibraryProject!false)>
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </#if>
        </activity>
    </application>
</manifest>

自动生成layout.xml布局文件

common/recipe_simple.xml.ftl
......
    <instantiate from="root/res/layout/simple.xml.ftl"
             to="${escapeXmlAttribute(resOut)}/layout/${simpleLayoutName}.xml" />
......

自动生成activity.java代码文件,并打开

recipe.xml.ftl
......
    <instantiate from="root/src/app_package/SimpleActivity.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/${activityClass}.java" />
......

4.template.xml

用户创建界面,用户获取用户输入的数据

template.xml
<?xml version="1.0"?>
<template
    format="5"
    revision="5"
    name="Empty Activity"
    minApi="9"
    minBuildApi="14"
    description="Creates a new empty activity">

    <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="generateLayout"
        name="Generate Layout File"
        type="boolean"
        default="true"
        help="If true, a layout file will be generated" />

    <parameter
        id="layoutName"
        name="Layout Name"
        type="string"
        constraints="layout|unique|nonempty"
        suggest="${activityToLayout(activityClass)}"
        default="activity_main"
        visibility="generateLayout"
        help="The name of the layout to create for the activity" />

    <parameter
        id="isLauncher"
        name="Launcher Activity"
        type="boolean"
        default="false"
        help="If true, this activity will have a CATEGORY_LAUNCHER intent filter, making it visible in the launcher" />

    <parameter
        id="backwardsCompatibility"
        name="Backwards Compatibility (AppCompat)"
        type="boolean"
        default="true"
        help="If false, this activity base class will be Activity instead of AppCompatActivity" />
    
    <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>

上面做了几件事

a. 模板类型

b. 用户输入

c. 执行

模板类型
<category value="Activity" />
给模板归类,类名相同的模板在创建代码的时候会在同个目录下
如果有多个项目,每个项目都有各自的模板,这时候就可以用以区分了,避免混乱了,毕竟放在Activity下面,会有很多系统内置的干扰

用户输入

template.xml
......
<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="generateLayout"
    name="Generate Layout File"
    type="boolean"
    default="true"
    help="If true, a layout file will be generated" />

<parameter
    id="layoutName"
    name="Layout Name"
    type="string"
    constraints="layout|unique|nonempty"
    suggest="${activityToLayout(activityClass)}"
    default="activity_main"
    visibility="generateLayout"
    help="The name of the layout to create for the activity" />
......

type 类型,string则是一个输入框,boolean则是一个checkbox

constraints是约束条件
nonempty:不能空则不能继续
unique:唯一,如果有重名文件存在,则会自动在后面加上数字标示,eg:Activity2.java
suggest自动完善,as会按照规则自动生成,用户不用因为有多个输入框而输入多个似是而非的数据
eg:上面的layoutName 会在用户输入activityClass后自动生成,LoginActivity --> act

执行

template.xml
......
    <globals file="globals.xml.ftl" />
    <execute file="recipe.xml.ftl" />
......

很简单的两句话,使用定义好的全局变量文件,执行recpie.xml.ftl创建模板

5.xxx.png

在创建的时候显示的图片,无视他

5.代码模板 SimpleActivity.java.ftl


package ${packageName};

import ${superClassFqcn};
import android.os.Bundle;
......

public class ${activityClass} extends ${superClass} {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
<#if generateLayout>
        setContentView(R.layout.${layoutName});
</#if>
......
}

这是一个ftl的模板
支持变量表达式${activityClass}
支持if else ,,在if 语句中,直接使用变量activityClass,不需要${}
这里使用的activityClass,generateLayout,layoutName都是在template.xml中定义的
superClass,packagename,superClassFqcn则是在globals.xml.ftl定义的全局变量
具体可以根据实际需求定制template.xml获取想要的数据,模板代码完全是可以copy+改

对于ftl模板而言,并不区分你的模板代码是xml还是java。所以,如果你想创建layout的模板,也是一样的方式,这里不再多说。

总结

plugin templates 模板虽然比起另外两种模板写起来麻烦很多,但他也同样的强大了许多。
另外,写模板的时候,需要重启as才能生效的,哪怕你是修改了一个字母,请重启生效,所以,建议在写模板的时候就新建一个空项目吧。


说了这么多废话,,下面进入正题


福利
福利
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容