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