Android アプリ開発独習メモ #1
Android アプリ開発の勉強を始めた。 とりあえず Android Developers の Getting Started の内容を順に進めていこうと思う。 この記事は適当なメモである。
- 本記事では “Building Your First App” の “Building a Simple User Interface” の内容まで進める
初心者なので間違いとかあれば指摘お願いします。
開発環境
プロジェクト作成
Eclipse を使うなら特に読まなくてもわかりそう。 ただプロジェクトを作るだけ。 コマンドライン使用者向けの情報も書いてあって、なかなかすごい。
プロジェクト作成時に Activity の作成もできる。 今回は例にのっとって “Blank Activity” を作成する。 (アクティビティのクラス名などはデフォルト値とした。)
プロジェクト作成時の項目
- Application Name : ユーザーに表示される名前。
- Project Name : ディレクトリ名とかに使われる。 ユーザーには表示されないぽい。
- Package Name : Java クラスのデフォルト (?) 名前空間となるパッケージ名。 Java の慣例に従い所有するドメイン名を逆向き (jp.ne.hatena.XXX) にしたもので始めるべき。
- Minimum Required SDK : アプリがサポートする Android の最低バージョンを [API level:title=http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels] で指定する。
- Target SDK : テストできる Android (?) の最高バージョンを API level で指定する。
- Compile With : どのバージョンの API level 向けにコンパイルするか (?)
アプリを動かす
- 資料 : Running Your App
これも Eclipse を使ってれば特に難しいところはない。 エミュレータは激重なので使い物にならない。
プロジェクト内の構成 (一部)
アプリを動かす前に重要そうなところだけ紹介されてる。
実機で動作させる
- 開発用 PC と実機を USB 接続する。
- Windows だと USB ドライバのインストールが必要 : OEM USB Drivers | Android Developers
- 特にドライバをインストールしなくても通常のデバイスとしては認識されたが、USB デバッグは OEM ドライバをインストールしないとできなかった。
- 実機の 「USB デバッグ」 を有効にする
- Eclipse の 「Run as」 で端末を選択してアプリを実行。
単純な UI を構築する
Android アプリの GUI は View と ViewGroup オブジェクトの階層構造によって構築される。 View オブジェクトは、通常 button や text field といった UI 部品であり、ViewGroup オブジェクトは view を格納する不可視の部品である。 ViewGroup は子の view がどのように配置されるかを定義する。 (例えばグリッドや縦方向のリスト、といった配置。)
Android は、View や ViewGroup のサブクラスに対応する XML の語彙を提供しているので、それらの要素の階層構造を使って XML で UI を定義することが可能となっている。
ここでは、プロジェクト作成時に生成された BlankActivity (“Hello World” が表示されるだけのアクティビティ) を編集し、テキスト入力欄と送信ボタンを表示するようにする。 (後からボタン押下時の動作が定義されるが、ここではボタンは存在するだけで押しても反応しない。)
リニアレイアウト (Linear Layout)
今回のプロジェクトの MainActivity で使用されるレイアウトは res/layout/activity_main.xml にある (プロジェクト作成時に自動的に作成されたもの)。 Eclipse でこれを開くと、最初はグラフィカルな表示になる (GUI で配置を設定できる WYSIWYG ツール)。 今回は直接 XML を編集したいので、“activity_main.xml” タブをクリックして XML エディタを開く。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" ... 属性いろいろ ... tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> </RelativeLayout>
もともと上記のようになっていて、RelativeLayout と TextView が使われていることがわかる。
今回はここをリニアレイアウトに変更してみる。 リニアレイアウトというのは、水平方向もしくは垂直方向に子要素を並べるものである。 リニアレイアウトを実現するために、ViewGroup の子クラスである LinearLayout を使用する。
<LinearLayout 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" android:orientation="horizontal" > </LinearLayout>
属性の意味は直観的にわかると思う。 (xmlns:tools って上の例の中だけだと要らないと思うけど、書くのが慣例なのかな。) レイアウトに関する詳細は Layout ガイドに書かれている。
テキストフィールド
ユーザーが編集可能なテキスト入力欄は EditText 要素 で表される。
<EditText android:id="@+id/edit_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/edit_message" />
先に記述した LinearLayout 要素の中に上の例のように EditText 要素を配置する。
android:id
属性 は、要素に対応する View オブジェクトを Java 側から参照するための一意の識別子を与える。 “@” 記号は、あらゆる XML からのリソースオブジェクトを参照するために必要とされる。 “@” 記号の後にリソースの種類 (今回の例では “id”) が続き、さらにスラッシュの後にリソース名 (今回の例では “edit_message”) がくる。
リソースの種類の前の加算記号 (“+”) は、リソース ID を最初に定義する際にのみ必要とされる。 アプリのコンパイル時、プロジェクト内の gen/R.java ファイルに新しいリソース ID を生成するために SDK ツールは ID 名を使用する。 リソース ID が一度定義されてしまえば、この ID に対する他の参照には加算記号は必要ない。 新しいリソース ID を指定する場合にのみ加算記号は必要なのであり、文字列やレイアウトのような具体的なリソースには必要ない (?)。 リソースオブジェクトの詳細は次の項目を参照のこと。
android:layout_width 属性 と android:layout_height 属性 は、その名のとおりビューの高さや幅を指定する。 この例では “wrap_content” という値が使われているが、これは、そのビューのコンテンツに合うサイズになるようにする指定である。 “match_parent” という値もあり、こちらを使うと親要素の大きさに合うサイズになる。
android:hint 属性 は、テキスト入力欄が空の場合に表示される文字列である。 この例の “@string/edit_message” というのは、別のファイルに定義された文字列リソースを参照する。 今はまだこの文字列リソースを定義していないのでコンパイルエラーが発生するが、この後文字列リソースを定義することで解消される。 今回の例では文字列リソースも要素 ID も同じ edit_message という名前を持っているが、リソースへのリファレンスは常にリソースの種類によって名前空間が分けられているので、同じ名前でも衝突はしない。
リソースオブジェクトについて
リソースオブジェクトは、単に一意な整数値の名前であり、それらはビットマップやレイアウトファイル、文字列といったアプリリソースに結び付けられている。
すべてのリソースには対応するリソースオブジェクトがあり、それらの対応関係はプロジェクトの gen/R.java ファイルで定義される。 R クラスのオブジェクト名を使用することでリソースを参照することが可能である。 さらに、android:id 属性を使用することでビューに対応する任意のリソース ID を生成することも可能である。
R.java ファイルは、コンパイル時に毎回 SDK ツールによって生成される。 このファイルを手で編集することはしてはいけない。
文字列リソースの追加
文字列はハードコーディングするのではなく、文字列リソースとして扱う方が多言語対応したりしやすくなるので良い。
デフォルトでは、res/values/strings.xml に文字列リソース用のファイルがある。 今回の例では、edit_message という名前の文字列リソースへの参照を先に使用したので、edit_message という名前の文字列リソースを追加しなければならない。 (hello_world という名前の文字列リソースへの参照は削除したので、この文字列リソースは削除して良い。)
また、後で使用する button_send という名前の文字列リソースも追加しておく。
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">My First App</string> <string name="edit_message">Enter a message</string> <string name="button_send">Send</string> <string name="action_settings">Settings</string> </resources>
ボタンの追加
送信ボタンを表すための Button 要素 を EditText 要素の後ろに追加する。
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" />
このボタンは Activity のコードから参照しないので android:id 属性は必要ない。
テキスト入力欄を広げる
ここまでのコードだと、テキスト入力欄は入力されたテキストに応じて幅が変わるものになっている (android:layout_width="wrap_content"
なので)。 高さはともかく、幅に関してはいえば最初から最大幅である方が良いだろう (スクリーンの幅のまだ使用していない部分も使用するようにテキスト入力欄の幅を大きくする)。 LinearLayout の中においては、android:layout_weight 属性 によって weight プロパティを指定することで、それが可能である。
weight の値は、余っている領域のうちどれだけの量をそのビューが消費するかを表す値である。 (自分も含めた) 兄弟要素の weight の合計値に対するそのビューの weight の値が、そのビューが消費できる余っている領域の割合である。
あらゆるビューの weight のデフォルト値は 0 である。 よって、weight を指定されたビューが 1 つしかない場合、そのビューがあまりの領域を全て使用する。
今回の例の場合、EditText 要素に android:layout_weight="1" という属性を付ければよい。 さらに、レイアウトの効率を上げるために、width はゼロ (0dp) にすると良い。