2012年11月24日土曜日

[Android] テンプレートを作成する(Activity編)

前回はプロジェクト作成時のテンプレートを作成しました。今回はActivityのテンプレートを作成します。

Activtyのテンプレートは
[SDK_ROOT]/tools/templates/activities配下にあります。

ここに空のListActivity(Activity+ListView)を作成するBlankListActivityというテンプレートを作成したいと思います。 基本的にBlanktActivityのテンプレートを元に作成します。

templates配下のフォルダ構成です。


template.xml
<?xml version="1.0"?>
<template
    format="3"
    revision="2"
    name="New Blank List Activity"
    description="Creates a new blank list activity.">

    <category value="Activities" />

    <parameter
        id="activityClass"
        name="Activity Name"
        type="string"
        constraints="class|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="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="navType"
        name="Navigation Type"
        type="enum"
        default="none"
        help="The type of navigation to use for the activity" >
        <option id="none" default="true">None</option>
    </parameter>

    <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>
        <!-- attributes act as selectors based on chosen parameters -->
        <thumb navType="none">template_blank_activity.png</thumb>
    </thumbs>

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

</template>

73行目でテンプレートのサムネイル画像を指定してますが、画像がないのでBlanktActivityのを使ってます(^_^;)

recipe.xml.ftl
<?xml version="1.0"?>
<recipe>
    <merge from="AndroidManifest.xml.ftl" />

    <merge from="res/values/strings.xml.ftl" />

    <instantiate from="res/layout/activity_simple.xml.ftl"
                   to="res/layout/${layoutName}.xml" />

    <instantiate from="src/app_package/SimpleListActivity.java.ftl"
                   to="${srcOut}/${activityClass}.java" />

</recipe>

globals.xml.ftl
<?xml version="1.0"?>
<globals>
    <global id="srcOut" value="src/${slashedPackageName(packageName)}" />
</globals>

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

    <application>
        <activity android:name=".${activityClass}"
            <#if isNewProject>
            android:label="@string/app_name"
            <#else>
            android:label="@string/title_${activityToLayout(activityClass)}"
            </#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>

ここまではBlankActivityのテンプレートをほぼそのまま使用してます。

strings.xml.ftl
<resources>
    <#if !isNewProject>
    <string name="title_${activityToLayout(activityClass)}">${escapeXmlString(activityTitle)}</string>
    </#if>

    <string name="text_empty">List is empty</string>

</resources>

activity_simple.xml.ftl
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".${activityClass}"
    android:orientation="vertical"
    android:layout_width=<#if buildApi lt 8 >"fill_parent"<#else>"match_parent"</#if>
    android:layout_height=<#if buildApi lt 8 >"fill_parent"<#else>"match_parent"</#if> >

    <ListView
        android:id="@android:id/list"
        android:layout_width=<#if buildApi lt 8 >"fill_parent"<#else>"match_parent"</#if>
        android:layout_height=<#if buildApi lt 8 >"fill_parent"<#else>"match_parent"</#if> >
    </ListView>

    <TextView
        android:id="@android:id/empty"
        android:layout_width=<#if buildApi lt 8 >"fill_parent"<#else>"match_parent"</#if>
        android:layout_height=<#if buildApi lt 8 >"fill_parent"<#else>"match_parent"</#if>
        android:gravity="center"
        android:text="@string/text_empty"
        android:textAppearance="?android:attr/textAppearanceLarge" >
    </TextView>

</LinearLayout>

ListViewのレイアウトです。ビルドAPIが8未満ではfill_parentを使うようにしてます。

SimpleListActivity.java.ftl
package ${packageName};

import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.app.Activity;

public class ${activityClass} extends Activity implements OnItemClickListener {

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

        ListView listView = (ListView) findViewById(android.R.id.list);
        listView.setEmptyView(findViewById(android.R.id.empty));
        listView.setAdapter(null);
        listView.setOnItemClickListener(this);
        listView.setOnCreateContextMenuListener(this);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // TODO 自動生成されたメソッド・スタブ
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        // TODO 自動生成されたメソッド・スタブ
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        // TODO 自動生成されたメソッド・スタブ
        return super.onContextItemSelected(item);
    }

}

ListViewを表示するActivityです。最低限必要なのだけ書いてます。

これでテンプレートは完成です。あとはEclipseから追加します。
プロジェクト作成時でも追加できますが、以下の手順で後からでも追加できます。
[ファイル]→[新規]→[その他]→[Android]→[Android アクティビティー]

アクティビティーの作成でBlankListActivityを選択し、Activity Nameなどを入力したら完了です。


これでListActivityが追加できるようになりました。

今回作成したのを置いておきます。BlankListActivity.zip

次回はその他のObjectのテンプレートを作成します。