AndroidStudio 模板 Template 生成代码 - 代码模板好,下班回家早



创建好的模板代码,里面包含MVP模式代码模板,需要的小伙伴可以自己下载导入到 C:\Program Files\Android\Android Studio\plugins\android\lib\templates 目录下,重启AS可以直接使用



android 中模板定义有3种

  • 1.代码片段模板 (Live Templates

  • 2.单文件模板 (File and Code Templates)

  • 3.多文件模板( Templates 主要用于具有通用样式的activity、fragment、mvp、MVVM代码创建)

今天我们主要介绍的是第三种,系统为我们提供的通用代码模板相比大家已经熟悉了,今天咱们就创建一个属于我们自己的模板



简单普及下代码模板

如何快速导入一个Live Templates

默认代码模板放在在这里 C:\Users\Jhon\.AndroidStudio3.5\config\templates

你可以自己添加,当然也可以去下载其他人的

https://github.com/keyboardsurfer/idea-live-templates

https://download.csdn.net/download/bencheng06/12283700

下载完成直接复制到你的 Android Studio config\templates目录下



概述

我们在使用Android Studio创建Activity、Fragment等等的时候,都会使用Android Studio提供的模板来简化我们创建的,使用模板时,我们只要做简单的配置,Android就能为我们生成相应的代码,所以使用模板可以提高开发的效率,接下来我们将学习如何去自定义一个符合自己项目框架的模板。


文章背景

我们知道,在Android开发中,官方提供了很多模板,可以直接创建成套的代码,很是方便开发

当你日夜加班写着重复的代码的时候有没有想过开发一个输入自己的代码模板,好吧就知道你想要,身体很诚实的小伙儿

一、首先你需要一个 TempateBuilder 插件安装

不要告诉我你不会哈,毕竟度娘这么发达

安装完成重启一下AS

二、建立自定义模板

以创建一个通用的列表act模板为例。

  • 代码最终实现的样式是这样的
1.话不多说,依次创建好这三个模板文件
  • 1.1 TempActivity.java

      ...
      
      public class  ${TempClassName} extends BaseActivity implements OnRefreshLoadMoreListener {
      
      
          @Bind(R.id.rl1)
          RelativeLayout rl1;
      
         	...
      
            
      
          @Override
          public int getContentView() {
              return R.layout.${LayoutName};
          }
      
          @Override
          public void initListener() {
              ...
      
              mAdapter = new BaseQuickAdapter<String, BaseViewHolder>(R.layout.${LayoutItemName}, null) {
      
                  @Override
                  protected void convert(BaseViewHolder helper, String item) {
      
                  }
              };
          }
    
      
         ...
      }
    
  • 1.2 activity 布局文件 LayoutName.xml

      <?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:id="@+id/activity_schedule_list"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical"
          tools:context="${packageName}.ui.${TempClassName}">
      
          <include layout="@layout/layout_backtitle" />
      
          <TextView
              android:layout_width="match_parent"
              android:layout_height="@dimen/qb_px_1"
              android:background="@color/color_hint_dcdcdc" />
      
      
      
      
          <com.scwang.smartrefresh.layout.SmartRefreshLayout
              android:id="@+id/mRefreshLayout"
              android:layout_width="match_parent"
              android:background="@color/color_bg_f0f0f0"
              android:layout_height="match_parent">
      
              <RelativeLayout
                  android:layout_width="match_parent"
                  android:layout_height="match_parent">
      
      
      
                  <android.support.v7.widget.RecyclerView
                      android:id="@+id/rv_list"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:layout_marginTop="@dimen/qb_px_30"
                      />
                  <TextView
                      android:id="@+id/view_background"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:background="#33000000"
                      android:visibility="gone" />
                  <${packageName}.customview.pagestatusview.CustomPageStatusView
                      android:id="@+id/page_status_view"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent" />
      
              </RelativeLayout>
      
          </com.scwang.smartrefresh.layout.SmartRefreshLayout>
      
      </LinearLayout>
    
  • 1.3 adapter布局文件 LayoutItemName.xml

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      
      </RelativeLayout>
    
2.选中这三个文件,ALT+T 抽取代码模板
  • 2.1 填写模板信息
  • 2.2 为代码中的每一个需要用户输入的变量创建变量属性,如 T e m p C l a s s N a m e 、 {TempClassName}、 TempClassName{LayoutName}、 L a y o u t I t e m N a m e 、 {LayoutItemName}、 LayoutItemName{packageName}
3.对生成好的模板进行高级编辑

生成好的代码存储在 C:\Program Files\Android\Android Studio\plugins\android\lib\templates 文件下,在这里我们可以看到很多系统的activity、fragment等

  • 在上图中,出现了三种文件,ftl、xml和png

    • ftl是freemarker文件,跟模板文件操作相关的操作都在ftl文件中定义

    • xml有两个,根目录下的template.xml定义了我们在使用模板时显示的界面;另一个res文件夹下的xml文件没有逻辑功能,将直接被复制到我们的工程中

    • png只有根目录下的那个文件,其实就显示在我们使用模板时显示的界面里,作为该模板的logo使用

我们再看看根目录下的三个文件的文件内容

  • 模板组成结构:

    • template.xml.fl :主要是给生成页面提供一些需要用户传入的参数
    • recipe.xml.ft : 配置要引用的模板路径和生成的文件的路径
    • globals.xmil.fl :主要提供一些全局参数
    • root文件:存放模板文件和资源文件效果缩路图


展开对每一个文件进行详细的介绍


1.template.xml.fl 定义了使用模板时的界面,我们先看LoginActivity的模板界面

我们看看template.xml如何定义这个界面

  • 定义模板类别
  • 定义输入项

容易看到,每个输入框的默认值、提示、类型等都是在xml中定义的。

主要的标签有

语法名称 描述 补充
<?xml version="1.0"?> 文件标准开头
子标签 父级标签 description:模板的描述信息
name:模板显示的名称
minBuildApi:最小构建版本限制,小于将无法创建
<-- 注释的信息 --> 支持多行代码注释
category 模板大分类,具有相同分类的模板将会被整理到一个标签下
parameter 创建一个输入项
thumbs 展示给用户的默认图,可以创建多张,尺寸必须为 512*512
globals 指向使用哪个全局变量文件的相对地址
execute 指向recipe.xml.ft文件的相对位置

比如一个完整的 .template.xml.fl 文件一般是如下这样的

	<?xml version="1.0"?>
	<template
	        format="5"
	        revision="6"
	        name="Basic Activity"
	        minApi="9"
	        minBuildApi="14"
	        description="Creates a new basic activity with an app bar.">
	
	    <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="navigationGraphName"
	            name="Navigation Graph Name"
	            type="string"
	            visibility="false"
	            suggest="nav_graph"
	            constraints="navigation|unique|nonempty"
	            default="nav_graph" />
	
	    <!-- 128x128 thumbnails relative to template.xml -->
	    <thumbs>
	        <!-- default thumbnail is required -->
	        <thumb>template_basic_activity.png</thumb>
	    </thumbs>
	
	    <globals file="globals.xml.ftl"/>
	    <execute file="recipe.xml.ftl"/>
	
	</template>

文件末尾不要忘记定义logo和包名

template的作用不止是定义模板的界面,事实上,通过在template里定义的id,其他ftl文件就可以获取我们在界面上输入的类名和文件名等,为自动生成文件和代码提供输入参数。

例如,在LoginActivity.java.ftl中,生成XXXActivity.java文件时,文件的名字,类的名字,都会根据template文件中activityClass的值进行赋值

  • 说明:
    • <template>中的 name 对应新建 Activity 时显示的名字
    • <category> 对应 New 的类别为 Activity
    • <parameter> 对应界面上蓝色框的一个项. id:唯一表示,最终通过该属性值,获取用户界面上的输入值,
    • name :界面上Label提示语
    • type :输入值类型取值 String/boleen
    • constraints :值约束 ,取值 class:类命名格式;layout: 布局格式; lunique:唯一的; nonempty :不可为空 ,通常为 constraints="layout |uniquel nonempty"或constraints=“class |uniquel nonempty”
    • visibility="template.xml任意一个id"控制这个id的显示和隐藏
    • suggest :建议值,比如填写ActivityName的时候,会给出LayoutName的建议值
    • help:底部显示的提示语

关联输入,需要注意的是,我们更改Activity Name时,Layout Name也会随之更改,这是通过“suggest=" a c t i v i t y T o L a y o u t ( a c t i v i t y C l a s s ) " ” 实 现 的 , 其 中 {activityToLayout(activityClass)}"”实现的,其中 activityToLayout(activityClass)"{activityToLayout()是个函数,用于把Activity的类名XXXActivity转换成Layout名activity_XXX;而这个函数的入参“activityClass”就是“Activity Name”这个输入框对应的id“activityClass”。

示例代码:

	<parameter
        id="TempMvpActivityId"
        name="Activity Name"
        type="string"
		constraints="class|unique|nonempty"
		suggest="${layoutToActivity(activity_temp_mvp_id)}"
        default="MyFirstMvpActivity"
        help="请输入Activity名称,驼峰命名并且全局唯一" />

	<parameter
        id="activity_temp_mvp_id"
        name="Activity Layout Name"
        type="string"
		constraints="layout|unique|nonempty"
		suggest="${activityToLayout(TempMvpActivityId)}"
        default=""
        help="请输入activity布局文件名称,全部小写、下划线分隔并且全局唯一" />

parameter中的常用的语法格式

语法名称
id="<temp_id>" 在源始模板文件中,指定的id,比如 "${temp_id}"
脚本运行时会动态替换模板文件的${temp_id},但是如果你在模板文件中定义了这个id但是没有给出对应的输入项,脚本将会报错,运行失败,因此所有的模板文件中的id都必须有唯一对应的id="模板中定义的id"的输入项
name="<输入项的标题>" 展示给用户的输入项的标题
type="<string/boolean>" 输入项接收值的取值类型,仅支持 stringboolean其中的一种,string 将会要求用户输入字符串信息, boolean则要求用户勾选是否
suggest="<输入项建议内容>" 根据某一条目id的取值,动态给出条目的建议内容。取值的形式有以下几种
1. 写死成常量值
2. 使用 ${条目的id} 函数,引用某一个id条目的取值
3. 如果是acitivity还可以使用 ${layoutToActivity(activity_temp_mvp_id)} 函数, 根据用户修改的layout文件名推测出activity名称
4. 如果是layout文件名称还可以使用 ${activityToLayout(activity_temp_mvp_id)} 函数, 根据用户修改的activity文件名推测出布局文件名称
如果我们定义的是资源文件名可以使用${classToResource(activity_temp_mvp_id)}函数进行转换
constraints="<输入项约束规则>" 约束规则有
class:需符合类的命名规则,首字母大写、驼峰命名
layout:输入内容须符合布局文件命名规范,下划线分隔、全部小写
unique:全局唯一
nonempty:输入值不可以为空
多个取值使用竖线分隔
class类文件固定使用为 constraints = “class | unique | nonempty”
layout类文件固定使用为 constraints = “layout | unique | nonempty”
visibility="<type="boolean"的输入项的id或者globals.xmil.fl中定义的全局变量>" 通过用户的勾选控制这个输入项是否显示给用户,visibility=“isCreateLayout”
enabled="<type="boolean"的输入项的id或者globals.xmil.fl中定义的全局变量>" 通过用户的勾选控制这个输入项是否可以被用户编辑
default="<输入项的默认值>" 输入项初始化时默认显示的内容
help="<选中输入框之后提示的帮助信息>"

2.recipe.xml.ftl用来定义如何生成代码和文件

·其他模板代码文件
除了根目录下的globals.xml.ftl、recipe.xml.ftl、template.xml三个文件,其他模板都可以根据需要自由配置。

  • 说明:
    • <#include> :导入另一个t文件
    • <open> :在代码生成后打开指定文件,例如,当我们创建一个 Activity 后, AS会自动打开Activity及布局文件。
    • <instantiate> :将 .ftl 文件转成 .java.kt 文件
    • <copy> :用于从root文件夹中复制文件到目标目录。
    • <merge> :用于合并文件,如将模板的strings.xml台并到我们项目中的 strings.xml

3.globals.xml.ftl 定义一些全局变量

示例:

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

里面定义的是一些全局变量,方便其他文件可以引用这里的值,引用的方式是 &{id的值}

最后可以看到还引用了另外一个 ftl,这也说明了这个文件里定义的属性同时也可以被其他模板引用

这个文件用于定义一些全局变量。

  • 说明:
    • <global) :表示一个全局变量
    • id:变量名
    • type :变量类型
    • value:默认值访问变量: ${变量id)

如上图所示,在globals里定义了一个与API版本有关的boolean值,这个值将在生成LoginActivity的代码时,用来判断是否要添加部分代码

4.root 底下还有一些相关文件介绍

  • build.gradle.ftl:project 的 build.gradle 模板,如果需要添加 maven 库的地址,就在这里添加
    gradle.properties.ftl:project 的 gradle.properties 的模板,如果需要添加工程的一些公用属性(版本号\版本名\签名信息\私有 maven 库的 group 和 id 信息等)就在这里面修改
  • local.properties.ftl:project 的 local.properties.ftl 模板,里面指定 SDK的路径,如果设置好环境变量,创建工程的时候就动态生成指定的路径,不需要手动修改
  • project_ignore:project 的.gitingore 模板,里面可以增删版本管理需要过滤的文件夹\文件
  • settings.gradle.ftl:project 的 settings.gradle 模板,里面可以指定真个工程需要编译的 module,这个建议不要修改,可以在工程中手动修改



5.注意:模板创建完成必须重启AndroidStudio

6.如果你使用自己创建的代码模板,出现中文乱码的情况,一定是模板文件编码格式不正确导致的,可以通过一定的编辑软件转换成UTF-8 无BOM 的编码格式,问题就可以解决了

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐