Android Studio 模板(Template)定制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/djk_dong/article/details/47130863

在我们创建Android工程,新建Activity时,Android Studio都会创建一些模板文件,比如创建Activity 可以选择BlankActivity,EmptyActivity,LoginActivity等等,可以帮我们轻松的构建一个基础的Activity(包含Activity文件,Activity对应的Xml文件,在AndroidManifest文件中注册Activity等),这时我们就可以轻松的跑一个helloWorld工程了。
相信大家一直都在用,有没有机会创建一个属于自己的模板呢?答案是肯定的,android Studio 内置的模板不能满足所有人的需求,因为不满足,所以才会有很好的方案出来,开始的动机很简单,每次创建Fragment的时候调用都会报错,因为版本兼容原因,我要用的是v4包里面的Fragment,而创建的Fragment默认导入的是系统的包,每次都要手动改,真心伤不起,不知道大家有没有遇到过这样的问题,一个偶然的机会在github上看到一位大神帮我解决了这个问题,其实也不算解决问题,只是帮我打开了思路,就是在android Studio 的安装目录\Android Studio\plugins\android\lib\templates下看到了所有模板,都是以文件的形式存在的,于是我决定写一个属于我自己的模板。
下面教大家定制属于自己的模板,下面以“BlankActivity”为例讲解:

1、首先,找到安装目录\Android Studio\plugins\android\lib\templates\activities,找到BlankActivity

新建一个eclipse空的工程,将BlankActivity复制到工程中,为了高亮显示ftl文件,可以安freemaker 插件
这里写图片描述

文件名 介绍
activity_simple.xml.ftl activity布局文件模板
main.xml.ftl 导航菜单模板
dimens.xml.ftl dimens.xml模板
strings.xml.ftl strings.xml模板
SimpleActivity.java.ftl activity模板
AndroidManifest.java.ftl AndroidManifest.java模板
globals.xml 全局参数设置
recipe.xml.ftl 根据模板生成对应的文件
template.xml 一些配置信息和参数
template_blank_activity.png 缩略图

下面我针对上述几个文件分别讲解
template_blank_activity.png就没有什么好说的啦,只是一张图片,有兴趣的话可以换一张自己喜欢的

template.xml 看下源码

<?xml version="1.0"?>
<template
    format="3"
    revision="4"
    name="Blank Activity"  //模板的名称,最好和文件夹相同
    minApi="7"
    minBuildApi="14"
    description="Creates a new blank activity with an action bar.">//这里是描述,可以修改成自己的描述

    <category value="Activity" /> //你会在新建文件 Activity文件夹下找到你的MyActivity
    <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="layoutName"
        name="Layout Name"
        type="string"
        constraints="layout|unique|nonempty"
        suggest="${activityToLayout(activityClass)}"
        default="activity_main"
        help="The name of the layout to create for the activity" />

    <parameter
        id="activityTitle"
        name="Title"
        type="string"
        constraints="nonempty"
        default="MainActivity"
        suggest="${activityClass}"
        help="The name of the activity. For launcher activities, the application title." />

    <parameter
        id="menuName"
        name="Menu Resource Name"
        type="string"
        constraints="layout|unique|nonempty"
        suggest="menu_${classToResource(activityClass)}"
        default="menu_main"
        help="The name of the resource file to create for the menu items" />

    <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="parentActivityClass"
        name="Hierarchical Parent"
        type="string"
        constraints="activity|exists|empty"
        default=""
        help="The hierarchical parent activity, used to provide a default implementation for the 'Up' button" />

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

globals.xml 定义全局变量,如manifestOut,srcOut,ResOut,Recipe.xml用到

<?xml version="1.0"?>
<globals>
    <global id="manifestOut" value="${manifestDir}" />
<#if hasDependency('com.android.support:appcompat-v7')>
    <global id="appCompat" type="boolean" value="true" />
    <global id="superClass" type="string" value="<#if buildApi gte 22>AppCompat<#else>ActionBar</#if>Activity"/>
    <global id="superClassFqcn" type="string" value="android.support.v7.app.<#if buildApi gte 22>AppCompat<#else>ActionBar</#if>Activity"/>
<#else>
    <global id="appCompat" type="boolean" value="false" />
    <global id="superClass" type="string" value="Activity"/>
    <global id="superClassFqcn" type="string" value="android.app.Activity"/>
</#if>
    <global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
    <global id="resOut" value="${resDir}" />
    <global id="relativePackage" value="<#if relativePackage?has_content>${relativePackage}<#else>${packageName}</#if>" />
</globals>

这里简单介绍下,Android Studio 使用的是freeMaker模板引擎,globals.xml中使用了简单freeMaker条件表达式if else语法很简单也容易理解,想要更深入的理解可以在百度搜索freemaker相关的教程。

recipe.xml 根据模板生成文件

<?xml version="1.0"?>
<recipe>

//将Activity注册到Manifest文件
    <merge from="AndroidManifest.xml.ftl"
             to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
//根据main.xml.ftl创建菜单布局文件
    <instantiate from="res/menu/main.xml.ftl"
            to="${escapeXmlAttribute(resOut)}/menu/${menuName}.xml" />
//插入activity名称到String.xml文件
    <merge from="res/values/strings.xml.ftl"
             to="${escapeXmlAttribute(resOut)}/values/strings.xml" />

    <merge from="res/values/dimens.xml.ftl"
             to="${escapeXmlAttribute(resOut)}/values/dimens.xml" />
    <merge from="res/values-w820dp/dimens.xml"
             to="${escapeXmlAttribute(resOut)}/values-w820dp/dimens.xml" />

//根据activity_simple.xml.ftl创建布局文件
    <instantiate from="res/layout/activity_simple.xml.ftl"
                   to="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />

//根据SimpleActivity.java.ftl创建Activity
    <instantiate from="src/app_package/SimpleActivity.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/${activityClass}.java" />

//打开activity文件
    <open file="${escapeXmlAttribute(srcOut)}/${activityClass}.java" />
    //打开布局文件
    <open file="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />
</recipe>

root文件夹中包含了各种模板文件,recipe.xml.ftl文件中有用到,到这里相信大家已经知道了大概的流程,接下来我们要开始写自己的模板了

SimpleActivity.java.ftl 其中${}包裹的就是template或者globals中声明的变量或者系统变量

package ${packageName};

import ${superClassFqcn};
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
<#if applicationPackage??>
import ${applicationPackage}.R;
</#if>

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.${layoutName});
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.${menuName}, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

其他文件就不一一展示了,都差不多
到这里相信大家已经了解了基本的流程,接下来就是定制属于自己的模板MyActivity,为了节省时间,我会在BlankActivity的基础上进行修改

提示:尽量不要在自己的电脑新建文件进行编辑,如要增加一个新的模板文件,复制原有的进行修改即可(自己建的文件在Android Studio 中编译不通过,具体原因也不是很清楚)

接下来我要对BlankActivity进行如下修改(根据我的个人习惯)
1、删掉Activity中一直没用到的函数onCreateOptionsMenu和onOptionsItemSelected。
2、删掉menu.xml,很少用
3、修改默认的布局,我不需要那些padding
4、我希望我的Activity都是竖屏的,label熟悉也不需要

修改之后的SimpleActivity.java.ftl是这样的

package ${packageName};

import ${superClassFqcn};
import android.os.Bundle;
<#if applicationPackage??>
import ${applicationPackage}.R;
</#if>

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.${layoutName});
    }

}

直接删,去掉多余的import

直接删除main.xml.ftl 并删除 recipe.xml.ftl 关联的代码

activity_simple.xml.ftl 修改后

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}">
  <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

AndroidManifest.xml.ftl修改如下

<manifest xmlns:android="http://schemas.android.com/apk/res/android" >

    <application>
        <activity android:name="${relativePackage}.${activityClass}"
            <#if isNewProject>
            android:label="@string/app_name"
            <#else>

            android:screenOrientation="portrait" //竖屏代码
            </#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>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            </#if>
        </activity>
    </application>

</manifest>

编辑过程中因为没有智能的编辑器
最后一步,将MyActivity丢掉activitys目录下,重启AS就可以用了
效果图:
这里写图片描述

资源下载 MyActivity

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页