android studio简单使用(A):自定义模版介绍

因为暂时还没有考虑好顺序,先用A表示


前言

自己也没有怎么接触过android studio的模版
只是参考 鸿洋 的博客,接触到了, 自己记录一下
具体参考:
https://github.com/WanAndroid/AndroidStudioTemplates

(后面
http://robusttechhouse.com/tutorial-how-to-create-custom-android-code-templates/
里面有说 用 freemarker ,最后生成java代码, freemarker记得之前的公司,Spring的页面有用到,感觉页面填充数据都差不多)


参考网站

鸿洋博客指向的github地址
https://github.com/WanAndroid/AndroidStudioTemplates
参考的是


自己参考

先参考


简单说明

Paste_Image.png
Paste_Image.png

这里大体的意思是,
通过开始做的参数,去做 recipe的执行
执行是将【前面的参数】,【recipe模版】和【Activity模版】,通过FreeMarker生成对应的 java文件


android studio中模版的位置

在 AndroidStudioXXXPath\plugins\android\lib\templates\中, 有对应的代码
以Activity为例:
我们打开android studio后, 在 File -- New -- Activity 中,可以看见很多可以选的Activity, 会显示显示符合条件的Activity模版


Paste_Image.png

AndroidStudioXXXPath\plugins\android\lib\templates\activities 中,有

Paste_Image.png

我们可以对比,基本一样的(文件夹中,有几个没有显示而已)


对应的文件

我们以 EmptyActivity 为例:
(因为自己猜测, 空的应该是最简单的)

Paste_Image.png

我们可以看见,对应的结构
大体为:

  • root 文件夹
  • 2个ftl模版文件
  • 1个xml文件
  • 一张图片

我们用大图看一下

Paste_Image.png

在把miniSdk, 新建 EmptyActivity , 可以看见对应的页面

Paste_Image.png

(对应的图片,和文件夹中的图片是一样的)


EmptyActivity 文件概要
  • root 文件夹
  • 2个ftl模版文件
  • 1个xml文件
  • 一张图片

我们先看一下

template.xml

<?xml version="1.0"?>
<template
    format="5"
    revision="5"
    name="Empty Activity"
    minApi="7"
    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="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>

一半猜测,一半看文档吧
先自己猜测一下(感觉代码都是差不多的,很多时候好的结构,可以猜到大概)
这是一个标准的xml

最外面 template, 可以猜测到

  • name: 名字, Empty Activity,新建的时候,显示的内容
  • minApi:最低api的版本(我们可以发现,gradle对应的版本如果写得过低,对应的模版是灰色不能选择的)
  • minBuildApi:最低的编译版本(同上)
  • description:描述,应该是显示在对话框中显示的描述

其他的变量:
category:类型,这里是 Activity
thumbs:android,java,maven都会见过,对应的thumbnail,缩略图,这里指向当前文件夹的一个文件(我们可以发现,如果修改名字后,新建模版就不会显示图片了)
globals:globals.xml.ftl,主观感觉,应该是一些全局的变量或者文件
execute:recipe.xml.ftl,主观感觉,应该是执行相关的

其他parameter们:
parameter:自己感觉就是对应的变量,别的地方可以使用的
一共有的parameter(3个string类型, 2个boolean类型)

  • activityClass: string 【Activity Name】
  • generateLayout:boolean【Generate Layout File】
  • layoutName:string 【Layout Name】
  • isLauncher:boolean【Launcher Activity】
  • packageName:string 【Package name】
Paste_Image.png

对应一下,上图
发现全部可以对应上, 并且默认值,可以里面的默认值是一样的


globals.xml.ftl

<?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>

前面几个 global id,应该都是 参数map,存放对应的id,type和value
最后有一个include
android,或者html页面,都经常用到的关键字
我们找一下对应的位置: ../common/common_globals.xml.ftl
( 无论是linux,php,win,貌似都一样,/ 开头,表示绝对路径; 其他表示相对路径)
我们到父文件夹找到common文件夹
找到对应的文件

Paste_Image.png

common_globals.xml.ftl

<globals>
    <#assign theme=getApplicationTheme()!{ "name": "AppTheme", "isAppCompat": true }>
    <#assign themeName=theme.name!'AppTheme'>
    <#assign themeNameNoActionBar=theme.nameNoActionBar!'AppTheme.NoActionBar'>
    <#assign appCompat=theme.isAppCompat!false>
    <#assign appCompatActivity=appCompat && (buildApi gte 22)>

    <global id="themeName" type="string" value="${themeName}" />
    <global id="implicitParentTheme" type="boolean" value="${(themeNameNoActionBar?starts_with(themeName+'.'))?string}" />
    <global id="themeNameNoActionBar" type="string" value="${themeNameNoActionBar}" />
    <global id="themeExistsNoActionBar" type="boolean" value="${(theme.existsNoActionBar!false)?string}" />
    <global id="themeNameAppBarOverlay" type="string" value="${theme.nameAppBarOverlay!'AppTheme.AppBarOverlay'}" />
    <global id="themeExistsAppBarOverlay" type="boolean" value="${(theme.existsAppBarOverlay!false)?string}" />
    <global id="themeNamePopupOverlay" type="string" value="${theme.namePopupOverlay!'AppTheme.PopupOverlay'}" />
    <global id="themeExistsPopupOverlay" type="boolean" value="${(theme.existsPopupOverlay!false)?string}" />

    <global id="appCompat" type="boolean" value="${((isNewProject!false) || (theme.isAppCompat!false))?string}" />
    <global id="appCompatActivity" type="boolean" value="${appCompatActivity?string}" />
    <global id="hasAppBar" type="boolean" value="${appCompatActivity?string}" />
    <global id="hasNoActionBar" type="boolean" value="${appCompatActivity?string}" />
    <global id="manifestOut" value="${manifestDir}" />
    <global id="buildVersion" value="${buildApi}" />

<#if !appCompat>
    <global id="superClass" type="string" value="Activity"/>
    <global id="superClassFqcn" type="string" value="android.app.Activity"/>
    <global id="Support" value="" />
    <global id="actionBarClassFqcn" type = "string" value="android.app.ActionBar" />
<#elseif appCompatActivity>
    <global id="superClass" type="string" value="AppCompatActivity"/>
    <global id="superClassFqcn" type="string" value="android.support.v7.app.AppCompatActivity"/>
    <global id="Support" value="Support" />
    <global id="actionBarClassFqcn" type = "string" value="android.support.v7.app.ActionBar" />
<#else>
    <global id="superClass" type="string" value="ActionBarActivity"/>
    <global id="superClassFqcn" type="string" value="android.support.v7.app.ActionBarActivity"/>
    <global id="Support" value="Support" />
    <global id="actionBarClassFqcn" type = "string" value="android.support.v7.app.ActionBar" />
</#if>

    <global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
    <global id="resOut" value="${resDir}" />
    <global id="menuName" value="${classToResource(activityClass!'')}" />
    <global id="simpleName" value="${activityToLayout(activityClass!'')}" />
    <global id="relativePackage" value="<#if relativePackage?has_content>${relativePackage}<#else>${packageName}</#if>" />
</globals>

我们可以发现更多的global参数,存放的map值


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>

我们发现被 recipe 包裹,

  • 有2个#include, 也就是对应 父文件夹下common文件夹的recipe_manifest.xml.ftl,recipe_simple.xml.ftl,对应的文件
    (具体就不跟了,应该也是添加对应的recipe相关的内容)

  • 第2个include前面,有一个 #if, 应该是判断, 后面这个字符串,如果大家观察前面文件仔细的话,在template.xml的parameter中有对应的值,默认为true

  • 后面大体应该是打开文件,创建文件等操作, 创建实例

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

应该就是打开 root下面唯一的SimpleActivity.java.ftl 模版文件,复制到对应template.xml的parameter为activityClass的值的文件中


简单总结

还是最上面的图


Paste_Image.png
Paste_Image.png

第一个图:
通过开始做的参数,去做 recipe的执行
也就是,在 template.xml 显示界面,并且获得对应参数的value,和globals.xml.ftl里面的value一起去做Recipe执行操作

第二个图:
执行是将【前面的参数】,【recipe模版】和【Activity模版】,通过FreeMarker生成对应的 java文件
这里图中 MyActivity.java.ftl 就是 上面例子中 SimpleActivity.java.ftl 文件

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

推荐阅读更多精彩内容