義援金の受付

東日本大震災の
復興支援へのご寄付
をお願い致します。

6. ユーザインターフェイス


Androidのアプリケーションにおいて、ユーザインターフェイスは、View 及び ViewGroup オブジェクトによって構築されます。 ViewとViewGroupにはさまざまなタイプがあり、それぞれがView クラスの派生クラスとなります。

View オブジェクトはAndroidプラットフォームにおけるユーザインターフェイスを表現する基本の構成単位です。View クラスは"ウィジェット"と呼ばれるサブクラスの基本要素を提供します。ウィジェットはテキストフィールドやボタンといった必要な実装が施されたUIオブジェクトを提供します。 ViewGroup クラスは、"レイアウト"と呼ばれるサブクラスの基本要素を提供します。レイアウトは、リニア、テーブル、相対などの異なる種類のレイアウト構成を提供します。

View オブジェクトとは、スクリーン内の特定の矩形エリアに対するデータ構造で、そのプロパティとして、レイアウトパラメータとコンテントを保持しています。 View オブジェクトは、スクリーン内に置かれている矩形エリアにおいて、それ自体の寸法、レイアウト、描画、フォーカスの変化、スクロール、キージェスチャによるインタラクションなどを制御します。 ユーザインターフェイス内のオブジェクトにとって、View は、ユーザとのインタラクトポイントであり、インタラクトイベントのレシーバでもあるのです。


ビュー階層

下の図に示すように、Android プラットフォームでは、View と ViewGroup ノードの階層を使用してアクティビティのUIを定義します。この階層ツリーは、シンプルにも、(必要に応じて)複雑にもでき、Android であらかじめ用意されているウィジェットやレイアウトのセットや自作のカスタムビューを使用して構成することができます。

ビューの階層ツリーをレンダリングし、スクリーンに貼り付けるためには、アクティビティがsetContentView()メソッドを呼び出し、ルートノードに対するオブジェクトの参照を渡す必要があります。Android システムは、この参照を受け取り、それを使って検証、評価してからツリーを描画します。階層のルートノードは、子のノードに対し自身を描画するよう要求します。 — 同じように、各ビューグループノードは、子のビューに対し、それぞれが自身を描画するよう要求をする責任があります。 子のノードは、親の中でのサイズや位置に対し要求を出すかも知れませんが、子の場所や大きさをどうするのかという最終的な決定権を持っているのは親のオブジェクトです。 Android は、レイアウトの要素を(階層の先頭から)順番にパースし、ビューをインスタンス化し、それらをその親(たち)に追加していきます。要素は順番に描画されるため、お互いが重なりあう位置にある場合は、後の方が先に描画された要素の前面に描画されてしまいます。

ビュー階層がどのように評価され描画されるのかに関する詳しい議論については、Android はどのようにビューを描画するのかを読んでください。


レイアウト

レイアウトを定義し、ビューの階層を表現するには、XMLレイアウトファイルを使用する方法がもっと一般的です。XMLはHTMLに良く似ていて、定義されたレイアウトを人が見て分かり易いようになっています。XMLの各要素は、View または ViewGroup オブジェクト(またはそれらの派生)のいずれかです。View オブジェクトはツリーの葉の部分にあたり、ViewGroup オブジェクトはツリーの枝にあたります(上のビュー階層図を参照)。

XML要素の名前はそれぞれが相当するJavaクラスの名前です。すなわち、要素 <TextView> は、TextView を UI に生成し、要素 <LinearLayout> は、LinearLayout ビューグループを生成することになります。レイアウトのリソースがロードされたとき、レイアウトの要素に相当するそれらの実行時オブジェクトがAndroid のシステムにより初期化されます。

例えば、テキストビューとボタンがあるシンプルな縦のレイアウトは以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView" />
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button" />
</LinearLayout>

LinearLayout 要素に、TextView と Button が含まれているところに注目してください。この中に別の LinearLayout (または他のタイプのビューグループ)をネストさせることができるので、ビュー階層を延ばしてより複雑なレイアウトを作成することが可能です。

UI レイアウトの構築に関するさらに詳しい内容については、レイアウトの宣言を読んでください。

ヒント: addView(View)メソッドを使用し、動的にView 及び ViewGroup オブジェクトを追加することで、Javaコード内でもView 及び ViewGroup を描画することが可能です。

ビューをレイアウトする方法はさまざまです。さらにいろいろな種類のビューグループを使用すれば、子のビューやビューグループを構成する方法は未知数になります。 Android により提供されている定義済みのビューグループ(レイアウトと呼ばれています)には、 LinearLayout、RelativeLayout、TableLayout、GridLayout、その他が含まれています。それらは、子のビューの位置を定義したり、レイアウトを構成したりするために使用する、それぞれ独自のレイアウトパラメータのセットを提供しています。

レイアウトで使用されるいろいろな種類のビューのいくつかについて知りたい場合は、 共通レイアウトオブジェクトを読んでください。


ウィジェット

ウィジェットとは、ユーザとインタラクトするためのインターフェイスを提供するビューオブジェクトです。 Android は、ボタン、チェックボックス、テキスト入力フィールドといった、すべてが実装済みのウィジェットを提供しているので、すぐにでも自分のUIを作成することができます。 Android が提供するより複雑なウィジェットには、カレンダーダイアログ、時計、虫眼鏡などがあります。しかし、Android プラットフォームが提供しているウィジェットの種類に制限は設けていません。さらにカスタマイズして、自分にとって実用的な要素を作成したい場合は、独自のView オブジェクトを定義したり、既存のウィジェットを拡張し組み合わせたりすることにより可能です。

詳しくは、カスタムコンポーネントの作成を読んでください。

Android が提供するウィジェットのリストは、android.widget パッケージを参照してください。


UI イベント

UI に何らかのビュー又はウィジェットを追加したら、ユーザとそれらとの間でインタラクトする方法を知りたくなるでしょう。それを知ればアクションを実行することができるようになりますから。UI イベントが通知されるようにするには、以下のふたつのうちのいづれかを行う必要があります。

  • イベントリスナを定義し、それをView に登録する。 多くの場合は、イベントをリッスンするのはこのやり方です。View クラスには、On<なんとか>Listenerという名前のネストされたインターフェイスのコレクションが含まれていて、それぞれがOn<なんとか>()というコールバックメソッドを持っています。例えば、View.OnClickListener (ビューのクリックをハンドリングする)、View.OnTouchListener (ビュー内のスクリーンでのタッチをハンドリングする)、そしてView.OnKeyListener (ビュー内でのキーボードによるキー押下をハンドリングする)などです。ビュー内で、それが"クリックされた"とき(ボタンが選択されたときのように)に通知してほしい場合は、OnClickListener を実装し、onClick()のコールバックメソッドを定義し、ビューにそのリスナーをsetOnClickListener()で登録します。
  • そのView の既存のコールバックメソッドをオーバーライドする。 これは、独自のView クラスを実装し、そこで発生する特定のイベントをリッスンしたいときに行うべき手法です。例えば、スクリーンがタッチされたときは(onTouchEvent())、トラックボールが動かされたときは(onTrackballEvent())、または、キーボードのキーを押されたときは(onKeyDown())をハンドリング可能なイベントの対象に含めます。こうすることで、カスタムビュー内での各イベントのデフォルトの振る舞いを定義し、そのイベントを他の子のビューに伝えるべきかどうかを決定することができるようになります。繰り返しますが、View クラスにはコールバックあり、それらを定義する唯一のチャンスはカスタムコンポーネントを作ったときです。

ユーザとビュー間のインタラクトのハンドリングについては、UI イベントのハンドリング を読み進めてください。


メニュー

アプリケーションメニューは、アプリケーションの UI におけるもうひとつの重要な部品です。メニューは、アプリケーションの機能や設定を見せる、頼れるインターフェイスを提供します。もっとも一般的なアプリケーションメニューは、デバイスのメニューキーを押すことにより現れます。しかしながら、コンテキストメニューも追加することができ、ユーザがアイテムを押し続けることで現れます。

メニューもまたビュー階層を使用して構成されていますが、その構成を自分で定義することはできません。その代わり、onCreateOptionsMenu() または onCreateContextMenu()コールバックメソッドをアクティビティに定義し、メニューに含めたいアイテムを宣言します。適切なタイミングで、Android が、そのメニューで必要な階層を自動的に生成して、メニューの各アイテムをその階層内に描画します。

メニューは自身のイベントをハンドリングも行い、メニューのアイテムにリスナーを登録する必要がありません、メニューにあるアイテムが選択されると、 onOptionsItemSelected() または onContextItemSelected() メソッドがフレームワークから呼び出されます。

アプリケーションのレイアウトとまったく同じように、XMLファイルにメニューのアイテムを宣言することもできます。

詳しくは、メニューの作成を読んで理解してください。


詳細なトピックス

ユーザインターフェイスを作成する基本を掴んだら、より複雑なアプリケーションインターフェイスを作成するための機能について探求していきましょう。

アダプタ

ビューグループになんらかの情報を投入したいのですが、ハードコードは避けて、代わりにデータを外部ソースにしてビューにバインドしたいと思います。そうするには、AdapterView をビューグループとして使用し、子のビューそれぞれの初期化とデータの投入は、そのアダプタからしてもらうようにします。

AdapterView オブジェクトは ViewGroup の実装で、与えられた Adapter オブジェクトにをもとにその子のビューを決定します。 Adpter はデータソース(おそらくは文字列配列)と AdapterView との間の世話役的な振る舞いをし、それを表示します。 Adapter クラスにはいくつかの実装があり、それらはカーソルからのデータベースのデータを読み込む CursorCursorAdapter や、任意の配列からデータを読む ArrayAdapter など特定のタスクに対するものです。

アダプタを使用したビューの投入に関してより詳しく理解するために、 AdapterViewにおけるデータのバインディング を読んでください。

スタイルとテーマ

おそらく、標準のウィジェットの見た目に満足していないと思います。それを変えるために、独自のスタイルとテーマを作成することができます。

  • スタイルとは、ひとつまたは複数のフォーマット属性のセットで、それらをレイアウト内で、個別の要素単位で適用することができます。例えば、ある決められたテキストサイズと色のスタイルを定義したい場合は、特定のビュー要素だけにそれを適用すればいいのです。
  • テーマとは、ひとつまたは複数のフォーマット属性のセットで、それらをアプリケーション内のすべてのアクティビティ単位で、またはひとつのアクティビティに対してのみに適用することができます。例えば、ウィンドウ枠の色とパネルの背景、およびメニューのテキストサイズと色を特定するセットとなるテーマとして定義することができます。このテーマは特定のアクティビティにもアプリケーション全体にも適用することができます。

スタイルとテーマはリソースです。Android は使用可能ないくつかのデフォルトのスタイルとテーマを提供しています。また、独自のカスタムスタイルとテーマを宣言することもできます。

スタイルとテーマの使用については、スタイルとテーマの適用 ドキュメントで理解してください。