スポンサーリンク

Androidアプリのモック(紙芝居)の作成時に,必要なソースコード:コピペ用の一覧表


Androidアプリの開発時,要件定義の段階で,

簡単な「紙芝居」(画面のモック)を作成するように依頼されることがある。

いわば,プロトタイピングである。


プロトタイプを使った開発の進め方と,そのメリット:

  • 顧客は,モックアプリを実際に端末上で操作して,操作感を試してみる。
    • モックが顧客のイメージ通りであれば,開発者に対してゴーサインを出す。
    • そうでなければ,モックは顧客に「気づき」を与え,「これでは使いづらい。」「よく考えたら,要件に漏れがあった・・・。」「大幅に方針を転換しよう!!」などの,積極的な効果をもたらす。
  • 開発者は,モックアプリを作成することによって,自分がアプリに対して抱いているイメージを具現化する。
    • 顧客がモックを気に入ってくれれば,そのモックから機能や画面を正式に洗い出して,工数見積もりとスケジュール作成に入ることができる。それをもって,要件定義工程が終了する。
    • もし,モックと顧客のイメージとの間にギャップがあれば,そのモックはNGを食らう。そのヒアリング結果に基づき,第二次プロトタイプ,第三次・・・と練り直してゆく。そのおかげで,開発の初期の段階で,顧客の要求を正確に抽出できる。


モックは,「紙芝居」でよい。

つまり,画面内にはダミー情報を埋め込み,DBアクセスや外部通信はしない。

それでもちゃんと,クリック操作などに反応して画面遷移をする。

「オブ脳」で有名な牛尾 剛氏の言葉を借りれば「ムービングはりぼて」である。


丁寧に画面設計書を作っても,「モバイル端末上での実際の使い勝手」を知ることは

できないので,こういった試作品の存在は非常に役立つ。



で,そのようなモックアプリを作る際には,開発者には「素早さ」が要求される。

生産性の非常に高い,いくぶん「機械的」な意味をも帯びた素早さである。

顧客としてはとにかく「早くイメージを見たい。とりあえず見て使って,その後でまた深く考えたい」のだから・・・。



Androidアプリで素早く,ラフな画面レイアウトを作成するためには,

ごく基本的なUIとその操作コードを使いこなせれば十分だ。

例えば,最終成果物では画像アイコン(ImageView)となっているべき個所は,

モック上では赤字で「※ここにアイコン画像」とTextViewで書いておけば済むことだ。



基本的なUIのコードを,素早く組み合わせて画面をさっと仕上げるためには,

コピペ用のライブラリがあると便利。


以下に,モックの作成に役立てるための,コピペ用のコードの一覧表を掲載する。

  • (1)表示側:よくあるレイアウト
  • (2)表示側:リストビューのひな型
  • (3)入力側:ボタンと画面遷移
  • (4)入力側:編集UI
  • (5)特殊なUI
  • (6)その他のリソース
  • 補足:プロトタイプを使ったアプリ開発の進め方


「はりぼて」を作るのに役立つコードのみ。

(1)表示側:よくあるレイアウト

(1−1)画面全体のスクロール

これをまず書かないと始まらない

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollView1"
    android:scrollbarAlwaysDrawVerticalTrack="true"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

<LinearLayout
    android:orientation="vertical"
    android:background="@color/page_bg_common"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <!-- 本体 -->



</LinearLayout>
</ScrollView>

※page_bg_commonという色に,各ページの共通背景色を定義しておく。


参考:

Androidでスクロールバーを表示する方法
http://magpad.jugem.jp/?eid=154

  • ScrollView>LinearLayout>縦長の要素たち という親子関係で配置すれば,縦スクロールバーが表示できる


how to see scrollview in graphical layout
http://stackoverflow.com/questions/51...

  • レイアウトXMLのGraphical Editor(gui)で,ScrollViewを設置すると縦長の高さを超過した下部が隠れて見えない。「3.6.1 there was an option called expand to fit」らしいが,左上の画面タイプでWXGAとかにして見て対処

なお,ヘッダ・スクロールビュー・フッタ という3部構成の骨組みが,下記のページでサンプルコードとして紹介されている。

RelativeLayout内で,
ヘッダ部にはlayout_alignParentTopを付け,
フッタ部にはlayout_alignParentBottomを付けている。

間に挟まるコンテンツ部分には,layout_belowとlayout_aboveを指定すればOK。

Android画面設計の基本
http://uky0426.wordpress.com/2011/01/...

  • Androidの場合、機種や縦・横など画面の見え方が画一的ではないのでできる限りスクロールバーなど内容を確認できる状態は確保した方がいい

(1−2)要素の右寄せ

重要でない要素や,目立たせたくない要素は右寄せ。

しかし,右寄せしてしまった場合,「左手の親指だけで操作しやすいかどうか」も要検討。

<RelativeLayout
    android:id="@+id/RelativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/btn1"
        android:text="@string/hoge"
        android:layout_alignParentRight="true"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_marginRight="10dp"
        android:textSize="15dp"
    ></Button>

</RelativeLayout>

画面右端はスクロールバーがかぶさってしまうので,marginRightを少し空けておくとよい。


参考:

右端と左端にボタンを設置したい時のレイアウト
http://aki-ino.blogspot.com/2010/03/b...

  • CSSでいうfloat:right, right=0 position=relative
  • RelativeLayout内で,要素のLayout AlignToParentRight=Trueにすればよい

(1−3)水平に並んだ3項目のうち,真ん中の要素の横幅をリキッドにしたい

左右のスミに,それぞれ固定幅のボタンがある。

その中間に,残った横幅の長さを全部使ってテキストを表示したい。

HTMLで言うと,ちょうど「width="*"」みたいな事をしたい。

    <!-- 3項目の並び -->

    <LinearLayout
        android:layout_width="fill_parent"
        android:id="@+id/linearLayout2"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:layout_height="wrap_content"
        android:layout_marginBottom="30dp"
        android:weightSum="1">

        <Button
            android:id="@+id/btn1"
            android:textSize="22dp"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_marginRight="10dp"
            android:text="@string/string1"
        ></Button>

        <TextView
            android:id="@+id/textView1"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="@string/string2"
            android:textColor="@color/black"
        ></TextView>

        <Button
            android:id="@+id/btn2"
            android:textSize="22dp"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_marginRight="10dp"
            android:text="@string/string3"
        ></Button>

    </LinearLayout>

「他の要素を先に配置させ,残った余白を幅として使わせたい要素」に対して

  • android:layout_weight="1"
  • android:layout_width="0dp"

を指定するところがポイント。


※なお,layout_weightを単独で使うと,下記のようなエラーになる。

Caused by: java.lang.RuntimeException: Binary XML file line #48: You must supply a layout_width attribute.

layout_width="0dp"を加えて解決。


参考:

Android SDK で, LinearLayout の動作を確認してみた.
http://noritan-micon.blog.so-net.ne.j...

  • 余った部分いっぱいに子部品を広げたいこともあるでしょう.そんな時には, weight 属性で,「どの部品に残り部分を占有させたいか.」を指定することができます
  • 占有する領域の広さは, weight に指定した値に比例する


という事はつまり,Androidアプリで「要素の右寄せ」をしたい場合,

  • RelativeLayout中で,対象要素をlayout_alignParentRight="true"にする
  • LinearLayout中で,対象要素の左側にある要素をlayout_width="1"で目いっぱい広げる

の2通りの方法がある,という事になる。


(2)表示側:リストビューのひな型

(2−1)項目の列挙(ListView):独自に行レイアウトを定義する場合

メインのレイアウトXML

    <!-- リスト -->
    <ListView
        android:id="@+id/listview1"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:background="@color/bg_listview"
        android:layout_marginBottom="30dp"
    />

※bg_listviewというcolorに,リストビューの背景色を定義しておく。


該当アクティビティ内のUI初期化コード

import android.widget.ListView;
import android.widget.ArrayAdapter;
import android.widget.AdapterView.OnItemClickListener;


public class MyActivity extends Activity implements OnItemClickListener {

    // リスト
    private ListView lv = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.page_no_namae);

        // 列挙したい項目
        String[] items_for_lv = {
        	"A",
        	"B",
        	"C"
        };
        // カスタム行レイアウトを使ってアダプタを生成
        ArrayAdapter<String> adapter_for_lv = new ArrayAdapter<String>(
            this, 
            R.layout.listview_one_line, 
            items_for_lv
        );
        // リストにアダプタをセット
        lv = (ListView)findViewById(R.id.listview1);
        lv.setAdapter(adapter_for_lv);
        lv.setOnItemClickListener(this);
    }

    // リストビューをクリック時
    public void onItemClick(AdapterView<?> parent,
        View view, int position, long id) {

        // クリックした要素内のテキスト文字列を取得
        String display_txt = (String)list_fr.getItemAtPosition(position);
        
        // positionとdisplay_txtに基づいて何らかの処理
        

        // 画面遷移
        Intent intent = new Intent(getApplicationContext(), NewActivity.class);
        startActivity(intent);
    }

listview_one_line.xml内で一行分のUIを定義

<?xml version="1.0" encoding="utf-8"?>

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="15dp"
    android:textColor="@color/black"
    android:background="@color/bg_listview"
/>


なお,Adapter定義時の第二引数には,Android内で定義済みのレイアウトを渡すこともできる。

その場合,行レイアウト用のXMLを準備する必要はなくなる。

もっとも単純な行レイアウトは android.R.layout.simple_list_item_1 で参照できる。

        // 組み込み済みの行レイアウトを使ってアダプタを生成
        ArrayAdapter<String> adapter_for_lv = new ArrayAdapter<String>(
            this, 
            android.R.layout.simple_list_item_1, 
            items_for_lv
        );

リストビュー(ListView)を使う
http://sites.google.com/site/androida...


R.layout
http://developer.android.com/intl/ja/...

  • simple_list系のメンバに注目

(2−2)項目の列挙(ListView):チェックボックス付き版

メインのレイアウトXML(前述と同じ)

    <!-- リスト -->
    <ListView
        android:id="@+id/listview1"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:background="@color/bg_listview"
        android:layout_marginBottom="30dp"
    />

該当アクティビティ内のUI初期化コード

import android.widget.ListView;
import android.widget.ArrayAdapter;

・・・

        // 選択させたい項目
        String[] items_for_checklist = {
        	"X",
        	"Y",
        	"Z"
        };
        // 組み込み済みの行レイアウトを使ってアダプタを生成
        ArrayAdapter<String> adapter_for_lv = new ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_multiple_choice,
            items_for_checklist
        );
        // リストにアダプタをセット
        ListView lv = (ListView)findViewById(R.id.listview1);
        lv.setAdapter(adapter_for_lv);
        
        // 複数選択可能にする
        lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

参考:

ListViewの選択モードを切り替える
http://techbooster.jpn.org/andriod/ap...

(3)入力側:ボタンと画面遷移

(3−1)水平中央に配置された,画面遷移用のボタン

    <!-- ○○画面へ遷移 -->
    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        android:weightSum="1"
    >

        <Button
            android:id="@+id/btn_goto_some_page" 
            android:layout_height="wrap_content"
            android:layout_width="300dp"
            android:layout_marginTop="30dp"
            android:layout_marginBottom="30dp"
            android:padding="20dp"
            android:textSize="22dp"
            android:text="@string/common_label_goto_some_page"
        ></Button>

    </LinearLayout>


ボタンを使って実際に画面遷移するコード:

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MyActivity extends Activity implements OnClickListener {

    private Button btn1 = null;
    private Button btn2 = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.hoge_page);

        // ボタン1
        btn1 = (Button)findViewById(R.id.btn1);
        btn1.setOnClickListener(this);

        // ボタン2
        btn2 = (Button)findViewById(R.id.btn2);
        btn2.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        if( v == btn1 )
        {
            Intent intent = new Intent(getApplicationContext(), Next1Activity.class);
            startActivity(intent);
        }
        else
        if( v == btn2 )
        {
            Intent intent = new Intent(getApplicationContext(), Next2Activity.class);
            startActivity(intent);
        }
    }
}

機械的に素早くコーディングするコツ:

  • 先にレイアウトXMLを作っておく。(そうすればActivity側でコンパイルエラーが出ない)
  • 既存のアクティビティをコピーして新規アクティビティのファイルを生成。
  • privateフィールドにボタンを列挙する。
  • onCreateで各ボタンにonClickイベントをセットする。
  • onClick内で,押されたボタンの種類に応じて,異なるイベントを起こす。

(3−2)OK/NGボタン付きのダイアログ

import android.app.AlertDialog;
import android.content.DialogInterface;

・・・

AlertDialog.Builder dlg = new AlertDialog.Builder( getApplicationContext() );
dlg.setTitle("ダイアログのタイトル");
dlg.setMessage("内容");
dlg.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
        // OKを押した場合の処理
        
    }
});
dlg.setNegativeButton("NG", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
        // NGを押した場合の処理
        
    }
});
dlg.show();

なお,「OKを押した場合の処理」の部分に何も書かなくても,ちゃんとOKボタンを押下した時にダイアログは閉じられる。


参考:

AlertDialogで警告画面を表示する(1)
http://techbooster.jpn.org/andriod/ap...


※onCreate以外のイベント(onResumeとか)でAlertDialogを構築する場合,Builder生成時に getApplicationContext() してしまうと下記のエラーになる。

java.lang.RuntimeException: Unable to resume activity {〜/〜Activity}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

この場合,かわりに this を渡せばよい。

Dialog throwing "Unable to add window token null is not for an application” with getApplication() as context
http://stackoverflow.com/questions/57...

  • But for the AlertDialog() neither getApplicationContext() or getApplication() is acceptable as a Context, as it throws the exception: "Unable to add window token null is not for an application”
  • Your dialog should not be a "long-lived object that needs a context". The documentation is confusing.
  • For some data structures it would make sense to make them static and based off the application's context, but generally not for UI related things, like dialogs.

その他,ダイアログに関する詳細:

Android SDK の動かないコード(初級編) ダイアログ上の要素にアクセスするとNullPointerExceptionになるエラー
http://language-and-engineering.hatenablog.jp/entry/20110908/p1


Android SDK の動かないコード(中級編) ダイアログにsetTitleしないと,ダイアログのサイズが最小になってしまう
http://language-and-engineering.hatenablog.jp/entry/20110909/p1

(3−3)画像アイコンをボタンとして機能させる

画像付きのボタン(ImageButton)の背景を透過させ,画像の縦横の長さををボタンの大きさにフィットさせればよい。

		<!-- ○○へ遷移 -->
		<ImageButton
		    android:id="@+id/imgbtn1"
		    android:layout_width="60dp"
		    android:layout_height="60dp"
		    android:layout_marginLeft="20dp"
		    android:layout_marginRight="20dp"
		    android:src="@drawable/logo_img"
		    android:scaleType="fitXY"
		    android:background="@android:color/transparent"
		/>


参考:

Android- Button Transparent
http://www.androidpeople.com/android-...

  • By using android:background="@android:color/transparent" the button background will become transparent


android:scaleType
http://developer.android.com/intl/ja/...

  • Controls how the image should be resized or moved to match the size of this ImageView.
  • scaleType="fixXY"でボタンの大きさに合わせて画像の大きさも変化してくれた

ところで,はりぼての段階では,まだ画像は無いはず。

そこで活躍するのがAndroid SDKに最初から組み込み済みの画像リソース達。

下記ページから,「ありがちなアイコン素材」のリソース識別子を確認できる。

Android 2.1 android.R.drawable Icon Resources
http://docs.since2006.com/android/2.1...

これらの存在を知っていれば,本番用の画像を作らなくても,それっぽいアプリのモック作成に役立つ。


これらの画像をJavaコード中で動的に参照する場合は,Rの代わりに「android.R」で書き始めればよい。

レイアウトXML中では,@drawableではなく,下記のように「@android:drawable」と指定すればよい。

	android:src="@android:drawable/ic_menu_help"

ただし,重要な注意を一点。

これらの組み込み画像リソースを,アプリ本番で利用してはならない。

OS内にビルトインされている画像リソースを使う場合,OSのバージョンが上がったら,画像も差し変わってしまうからだ。

アプリ本番でも使いたい素材があれば,resフォルダ内にコピーを設置して利用すべきだ。
そうしないと,思わぬところで表示がバグる事になる。

ビルトインの画像は,アプリ内に組み込まれるのではなく,アプリ外部の端末内のリソースを「参照」しているに過ぎないのだ。

android.R.drawable.ic_menu_home - can not use
https://groups.google.com/forum/?from...

  • We don't recommend using the built-in icons. This has already been discussed fairly in-depth - you end up with the worse situation of the icons in your app being inconsistent
  • the only thing you can keep consistent is your own icons within your own app

(3−4)ダイアログ上に選択メニューを表示したい

AlertDialogにsetItemsして選ばせる。

	final String[] setting_items = {"A画面へ", "B画面へ", "キャンセル"};
	final Context context = this;

	new AlertDialog.Builder(this)
	.setTitle("画面遷移先")
	.setItems(setting_items, new DialogInterface.OnClickListener() {
	    public void onClick(DialogInterface dialog, int index) {
	    	Intent intent;
	    	switch( index )
	    	{
			case 0:
				// A画面へ
				intent = new Intent(context, AActivity.class);
	    		startActivity(intent);
	    		break;
			case 1:
				// B画面へ
				intent = new Intent(context, BActivity.class);
	    		startActivity(intent);
	    		break;
			default:
				// キャンセル
				dialog.cancel();
	    	}
	    }
	})
	.show();

(4)入力側:編集UI

(4−1)入力項目名と,入力ボックスが水平に並んでいる

    <!-- ○○を入力 -->
    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal"
    >

        <TextView
            android:id="@+id/textView2"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@color/black"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="@string/input_label_edit1"
        ></TextView>

        <EditText
            android:id="@+id/editText1"
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:layout_height="wrap_content"
        ></EditText>

    </LinearLayout>

(4−2)選択肢の固定されたスピナー

レイアウトXML

    <!-- 選択 -->
    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
    >
            <Spinner
                android:id="@+id/spinner1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:entries="@array/arr_spinner1"
            ></Spinner>

    </LinearLayout>


strings.xml

    <string-array name="arr_spinner1">
        <item>選択肢1</item>
        <item>選択肢2</item>
    </string-array>

モックの段階では,エントリを動的に操作することはないだろう。


※Spinnerのエントリを静的に指定している限り,Spinnerのスタイルは simple_spinner_dropdown_item になってくれて,指の太い人でも押しやすいはず。

エントリを動的に設定している場合,スタイルを明示的に指定しない限り android.R.layout.simple_spinner_item になってしまい,細くて押しづらい。

Spinnerを複数行表示にする方法
http://magpad.jugem.jp/?eid=101

  • android.R.layout.simple_spinner_item
  • android.R.layout.simple_spinner_dropdown_item

(4−3)画面を開いたとき,自動的に編集用キーボードを表示させたくない

画面中にEditTextビューがあると,画面を開いたときに自動的にそのEditTextにフォーカスが当たり,文字入力用のキーボードが画面下半分に表示されてしまう。

そうすると,画面全体のレイアウトを確認するためには不便な場合がある。


この挙動を解消するためには,まずレイアウトXML中で EditText タグ内に requestFocus タグが存在するかどうかを確認し,あれば除去する。


次に,アクティビティ中で,setContentView() よりも前に下記のコードを記述する。

this.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

import android.view.WindowManager.LayoutParams; が必要。

Androidアプリで、起動後最初にカーソルを当てるViewを指定する方法
http://android.roof-balcony.com/view/...

  • フォーカスを当てたいViewに、requestFocusタグを付けるだけ
  • requestFocusを設定していない場合の動作は、特に既定されていない。既定されていない、という事は、自分で設定しておく事が望ましい


Android - Activity 起動時にキーボードを表示させない
http://michelle-gf.blogspot.com/2011/...

(5)特殊なUI

(5−1)ダイアログ

自動的に消える:

import android.widget.Toast;

・・・

Toast.makeText(getApplicationContext(), "hoge", Toast.LENGTH_LONG).show();

ボタン押下時に,「ダミーボタン:○○処理をする」のようなメッセージを表示させる。


(5−2)画像表示(ImageView)

    <ImageView
      android:id="@+id/ImageView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:src="@drawable/icon"
    ></ImageView>  

drawableの各フォルダ内に,解像度に応じたicon.pngがあること。

  • hdpi
  • mdpi
  • ldpi

のそれぞれで解像度の高さが異なるが,モックの段階ではとりあえず「ldpi」にだけ画像を保管しておけば,画面の描画はできる。


(5−3)MapViewによる地図 (Google Maps)

レイアウトXML:

<LinearLayout
    android:layout_width="fill_parent"
    android:id="@+id/linearLayout1"
    android:gravity="center_vertical|center_horizontal"
    android:layout_height="330dp">

    <!-- マップ -->
    <com.google.android.maps.MapView
        android:id="@+id/map_view"
        android:clickable="true"
        android:enabled="true"
        android:layout_width="fill_parent"
        android:layout_height="300dp"
        android:apiKey="(デバッグ用のAPIキー)"
    ></com.google.android.maps.MapView>

</LinearLayout>

モックはEclipseからデバッグ起動するので,本番用ではなくデバッグ用のAPI Keyを使う点に注意。


AndroidManifest.xml:

applicationタグ直下に,Google Mapsの呼び出し宣言を追記:

    <uses-library android:name="com.google.android.maps" />

manifestタグ直下に,インターネットの利用許可を追記:

<uses-permission android:name="android.permission.INTERNET" />


アクティビティ側:

package com.example;

import android.os.Bundle;
import com.google.android.maps.MapActivity;

public class GmaptestActivity extends MapActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        MapView map = (MapView)findViewById(R.id.map_view1);
        map.setBuiltInZoomControls(true);
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

}


参考:

Androidアプリで,Google Maps API+GPS+Geocoderを使って,現在地の地図と地名を表示させよう
http://language-and-engineering.hatenablog.jp/entry/20110828/p1

(5−4)アプリを終了させるUI

アクティビティ内で:

	// 戻るボタンが押されたときに終了させたい
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_BACK){
			moveTaskToBack(true);
			return true;
		}
		else
		{
			return super.onKeyDown(keyCode, event);
		}
	}

なお戻るキー関連は,2.x系であれば専用のメソッドが存在する。

戻るのを無効化させるためには,keyEventとか使わずにonBackPressedイベントをハンドルするだけで済む。

@Override
public void onBackPressed() {
    super.onBackPressed();
}

[Android]戻るボタンが押されたときに処理を入れる
http://www.pshared.net/diary/20101002...

(6)その他のリソース

(6−1)strings.xmlのひな型

ネーミング規約付きで

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- color(物理色) -->
    <color name="white">#FFFFFF</color>
    <color name="black">#000000</color>
    <color name="gray">#808080</color>
    <color name="red">#FF0000</color>
    <color name="blue">#0000FF</color>

    <!-- color(論理色) -->
    <color name="page_bg_common">#87CEFA</color>
    <color name="bg_listview">#ADFF2F</color>



    <!-- 単一文字列 -->

    <string name="(画面の識別子)_(部品タイプ)_(役割概要)">文字列の内容</string>



    <!-- スピナー用,文字列配列 -->

    <string-array name="arr_(画面の識別子)_(役割概要)">
        <item>要素1</item>
        <item>要素2</item>
    </string-array>

</resources>
  • 画面の識別子:Activity名を簡略化した物。LoginActivityならばlogin。
  • 部品タイプ:UIの種類を簡略化した物。ボタンラベルならbtn。リテラル(べた書き用の文字列)ならlabel。
  • 役割概要:該当文字列の役割の概要。ログアウトの説明用の文言ならguide_for_logout。

補足1:プロトタイプを使ったアプリ開発の進め方

まず,顧客は企画を立ち上げる。

開発者は,顧客から要件をヒアリングする。


その後,プロトタイプとして,紙芝居アプリを作る。

その際には・・・

  1. まず,おおまかな機能の分類をメモする。
  2. 次に,画面遷移図の「たたき台」を作る。
    1. 紙ベースで作ってもよい。大きな紙に黒で原案を書いて,加筆修正は赤や青で書き込む。
    2. あるいは,Excelのシェイプにコネクタをつなげて画面遷移図とし,画面構成は各シェイプ内に文字ベースで(AA)として書き込む。
  3. 画面遷移図のたたき台(紙)を手元に置きながら,一つ一つの画面のモックを実装してゆく。
    1. 本稿のコピペ用ソースコードを大いに活用して,実装時間を短縮する。
    2. 1画面を実装し終えるたびに,遷移図上でその画面にチェック印を書き込む。
    3. もし追加で画面やUIが必要になったら,紙ベースで赤字で修正する。たたき台に過ぎないので,遷移図の元ファイルを修正しようとしない(時間が無駄)。
  4. 意味のあるまとまりごとに,数画面作り終えるたびに,実機で動作確認してみる。実装した画面間で行き来できることを確かめる。(以外と,AndroidManifest.xmlにアクティビティ名を書き忘れていた!とか,違うレイアウトをsenContentしていた!などの実行時エラーが多い。)
  5. できるだけ素早く全体を仕上げ,顧客からのフィードバックを得る。そうしたら,手順の最初に戻って,同じことを繰り返す。


第 n 次プロトタイプが完成した時点で,顧客からゴーサインが出たとしよう。

その後の作業は

  • 機能を洗い出し,簡単に一覧表にまとめ
  • 画面を洗い出し,簡単に一覧表にまとめ
  • 各画面にかかる実装工数と単体試験工数,および機能ごとの結合試験工数の積算により,工数見積もりとスケジュールを作成

となる。

これで要件定義は終わり。


承認を得たら,基本設計に取り掛かる。

  • 各画面での共通処理を抽出して,基底アクティビティやUtilクラスにまとめる。パッケージも,ファイルが平積みにならないように適切に分割。共通UIも独自Viewとして定義。
  • ストレージを使う場合は,DB設計を行なう。
  • 通信する場合は,外部APIを洗い出し,サブシステムとして連携方法やポジションをまとめる。
  • 環境要件(Android OSのバージョンとか)やアプリの目的,全体アーキテクチャ,システムテストの計画などを軽くまとめて基本設計書とし,顧客のレビューを通す。


その後,詳細設計+実装+単体テストに取り掛かる。

これは,ゴリゴリJavaでコーディングするのみ。

Androidフレームワークの基本構成の理解や,デザインパターンなどの設計知識があれば,「詳細設計」という名のもとに格別なことをする必要はない。(適切なJavadocコメントが伴えばの話だが)

ただ,DBのドメイン定義,通信フローの定義,時系列の複雑な状態変化の仕様などは,文書化を済ませておかないと危険。


結合試験,システムテストも無事に終わったら,マーケットに公開し,PR活動を行う。

そしてユーザの反応を見ながらバージョンアップしてゆく。


補足2:参考URL

関連エントリ:

今から1時間で,Androidアプリの開発環境を構築し,Windows上でサンプルを動作させる手順
http://language-and-engineering.hatenablog.jp/entry/20110724/p1


WebアプリとAndroidアプリのアナロジー (「Androidのアレは,Webで例えるなら○○だ」)
http://language-and-engineering.hatenablog.jp/entry/20110813/p1


用語について,厳密な話:

プロトタイプとモックアップの違い
http://d.hatena.ne.jp/january/2008073...

  • プロトタイプ=最終成果物でも利用する
  • モックアップ=使い捨て

cf. ISO/IEC TR 14759 : 1999


モック作成のために有用なUIのコードは,逐次追加される。