アナログ金木犀

つれづれなるまままにつれづれする

Androidでファイル群テンプレートを作る話

File TemplateとかProject Templateは作れるのは知っていたのですが、

Files Templateって作れないのかなーと思ってました。

設計によってはある機能や画面を作る度に似たようなクラス群を作ったりしますしね。

ちょっと調べてみたら Project Templateと同じ要領で作れたので紹介します。

(Macでの開発を前提として書いていきます)

デフォルトのテンプレートの置き場所

Project Template同様、下記に置いてあります。

/Applications/Android Studio.app/Contents/plugins/android/lib/templates/

作り方

下記を用意します。

  • template.xml
  • globals.xml.ftl
  • recipe.xml.ftl
  • 作りたいテンプレート
template.xml

このFiles Templateの概要をtemplate.xmlに載せます。例はこんな感じ。

<?xml version="1.0"?>
<template
    name="Template Name"
    description="make screen template"
    revision="1"
    format="5">

    <category value="MyCategory"/>

    <parameter
        name="Class Name"
        constraints="unique|nonempty"
        default="ClassName"
        id="className"
        type="string"/>

    <parameter
        name="Resource Name"
        constraints="unique|nonempty"
        default="resName"
        id="resName"
        type="string"/>


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

</template>

template タグにこのFiles templateの説明を。

category にカテゴリ名を。

f:id:kgmyshin:20170103170208p:plain

上のOtherService がカテゴリ名です。自分の場合は、汎用的でないがあるプロジェクトでやたら使うテンプレートとか作るときにプロジェクト名をカテゴリ名としてたりします。

parameterには自分が入力したいパラメーターを。上のxmlだと下記のようになります。

f:id:kgmyshin:20170103171247p:plain

globals.xml.ftl

ここには様々なファイルパスを定義しておきます。必要なものだけで良いです。

<?xml version="1.0"?>
<globals>
    <global id="resOut" value="${resDir}" />
    <global id="manifestOut" value="${manifestDir}" />
    <global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
    <global id="unitTestOut" value="${escapeXmlAttribute(projectOut)}/src/test/java/${slashedPackageName(packageName)}" />
    <global id="relativePackage" value="<#if relativePackage?has_content>${relativePackage}<#else>${packageName}</#if>" />
</globals>
recipe.xml.ftl

root ディレクトリを作ってそこにテンプレートを作っておきます。 (下記を参考)

recipe.xml.ftl ではディレクトリを作ったり、テンプレートからファイルを作成したり、コードをマージしたりできます。

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

    <instantiate from="root/src/app_package/Activity.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/${className}Activity.java" />
    <instantiate from="root/src/app_package/Contract.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/${className}Contract.java" />
    <instantiate from="root/src/app_package/Fragment.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/${className}Fragment.java" />
    <instantiate from="root/src/app_package/Presenter.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/${className}Presenter.java" />


    <instantiate from="root/res/layout/activity.xml.ftl"
                   to="${escapeXmlAttribute(resOut)}/layout/activity_${resName}.xml" />
    <instantiate from="root/res/layout/fragment.xml.ftl"
                   to="${escapeXmlAttribute(resOut)}/layout/fragment_${resName}.xml" />

    <merge from="root/AndroidManifest.xml.ftl"
             to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
</recipe>

上記では

  • HogeActivity, HogeContract, HogeFragment, HogePresenterクラスを作成
  • activity_hoge.xmlfragment_hoge.xmlを作成
  • AndroidManifest.xmlにテンプレートの内容をマージ

ということをやってます。

使ってみる

Cmd + N を押して「New」を開いて下の方に行くと

f:id:kgmyshin:20170103175739p:plain

こういうのが出てくるのであとはパラメータを入力して実行です。

共有方法とか

汎用的なテンプレートならgithubに全公開とかでいいと思いますが、プロジェクトに閉じたものならプロジェクトのgit管理下に置いて運用するのがいいと思います。

/Applications/Android Studio.app/Contents/plugins/android/lib/templates/

に、コピーしてくださいというのも面倒なので、スクリプトを用意してそれもセットにして管理しておくのがオススメ。

注意

/Applications/Android Studio.app/Contents/plugins/android/lib/templates/

配下にテンプレートを置いておくとアップデート時にvalidation errorになります。

アップデートの時は削除しましょう。

終わりに

次回のkyobashi.dexでこのことも話そうと思います。

rmp-quipper.connpass.com

多分これに関してはこっちの方が詳しくなってるかもですが、それ以外のことも似たようなことを話そうかと。

何か聞きたいこととかあれば是非来てください。m m