「Implementing a User Interface」の一部翻訳

Implementing a User Interface」の一部を翻訳しました。
pdf版はこちら

ユーザーインターフェースの実装

 このセクションではAndroidの画面のユーザインタフェースを実装する基本的な方法を記載します。
画面を作る為の基本とXMLで画面を定義してコードからロードする方法、その他ユーザーインタフェースを取り扱う為に必要な色々なタスクについて解説します。

画面構成要素の階層

 Androidアプリケーションの基本的な機能単位としてandroid.app.Activityクラスのオブジェクトがあります。
アクティビティで様々なことをすることができますが、それ自体では画面上に何も表示しません。
アクティビティを画面上に存在させ、UIを設計するには、ViewやViewグループを使います。

Views

 Viewはandroid.view.Viewクラスのオブジェクトです。画面上の特定の矩形領域に対するレイアウトとコンテンツのプロパティを持ちます。
 Viewオブジェクトは画面領域の為に画面サイズ、レイアウト、描画、フォーカス変更、スクロール、キー/ジェスチャーを扱っています。


 Viewクラスはwidgets(インタラクティブに画面要素を描画するサブクラスを実装した集合)用の基本クラスを供給します。
 Widgetsは測定と描画を処理するので、より早くUIを構築することができます。
 利用できるインターフェースには、Text、EditText、InputMethod、MovementMethod、Button、RadioButton、Checkbox、ScrollViewがなどがあります。

Viewgroups

 Viewgroupsはandroid.view.Viewgroupクラスのオブジェクトです。
その名前が示すようにViewgroupsはViewとViewgroup配下のセットを含み、管理するための機能を機能を持つ特別なViewオブジェクトです。
 ViewgroupsはストラクチャをUIに追加し、一つの実体と呼ぶことのできる複雑な画面要素を構成します。
 Viewgroupクラスはレイアウト(一般的な画面レイアウトを提供するサブクラスのセット)の基本クラスを供給し、Viewのセットを構築する方法を提供します。

UIのツリー構造

 Androidプラットホームでは、下記の図で示すようにViewとViewgroupノードのツリーを使っているアクティビティのUIを定義します。ツリーは単純にも複雑にも好きなように作成することができ、あらかじめ定義されたwidgetsとレイアウト、自分でカスタマイズしたviewタイプを使って構成することができます。

 画面にレンダリングしてツリーに関連付けるには、アクティビティで、setContentView()メソッドを呼び、
ルートノードオブジェクトへの参照を渡します。
 一旦Androidシステムがルートノードオブジェクトへの参照を持てば、Androidシステムはノードをダイレクトに操作し、画面の消去、測定、描画を行うことができます。
 アクティビティがアクティブになり、フォーカスを受け取った時、システムはアクティビティに通知し、ルートノードにツリーを測定、描画するように要求を出します。ルートノードは子ノードの描画を要求します。(描画要求を受け取った時、ツリーの各viewgroupのノードは自分の直下の子ノードに対して描画要求する義務があります。)


 上記のように各viewgroupは、利用できるスペースを測定する責任を持ち、子ノードを配置し、各子ノードにレンダリングさせるためににDraw()を呼びます。
 子ノードは親ノードのサイズと位置を要求するかもしれませんが、親オブジェクトが、各子ノードのサイズと位置を最終決定します

子ノードの位置とサイズの指定方法

 すべてのViewgroupクラスは、ViewGroup.LayoutParamsを拡張した入れ子になったクラスを使用します。このサブクラスは子ノードのサイズと位置を定義するプロパティを含んでおり、Viewgroupクラスのプロパティに割り当てられます。


 LayoutParamsサブクラスには値を設定する為に各々の文法があるので注意が必要です。各子要素は、親ノードにふさわしいLayoutParamsを定義しなければなりません。
 しかし、子ノードに異なるLayoutParamsを定義することもできます。


 サイズを合わせるのに頻繁に使うのは、コンテンツのサイズから計算するか、親オブジェクトのサイズまでオブジェクトのサイズを大きくすることを許可する方法です。(訳注:パラメータ指定で親オブジェクトのサイズに合わせることが出来る。)

一般的なレイアウトオブジェクト

 以下は、アプリケーションで使う最も一般的なViewgroupsです。
各タイプについての基本的な情報を解説しています。
(詳細については各項目のリンクされたページを参照してください。)

FrameLayout

 FrameLayoutは、最も簡単なレイアウトオブジェクトです。
FrameLayoutは、空白の、予約された空間としてスクリーン上に用意され、画像などの一つのオブジェクトを入れることができます。
 すべての子要素はスクリーンの左上に配置されます。FrameLayoutでは子要素の位置を指定することはできません。
 子要素は、以前のオブジェクトの上に上書きし、(新しいオブジェクトが透明でなければ)以前のオブジェクトを部分的に、あるいは全体的に覆い隠すことになります。

LinearLayout

 LinearLayoutは、一つの方向にすべての子要素を配置します。
その方向は−垂直または水平があり、LinearLayoutに設定したプロパティによって決まります。
全ての子要素は次々にスタックされ、垂直のリストはどれだけ横幅が広くても、行ごとに一つだけ子要素を持つことになり、水平のリストは高さ(子要素の中で最も長い縦幅+パディング)をもつ一つだけの行を持ちます。
 LinearLayoutは子要素の間のマージンや、重力(子要素のright、center、leftの属性)も考慮します。


 子要素はweight値を指定し、残りのスペースは宣言されたweightの割合で子要素に割り当てられます。
 デフォルトのweightはゼロです。
 例えば3つのテキストボックスがあって、そのうち2つはweightを"1"で宣言している場合、"1"で宣言したテキストボックスは余白のスペースをいっぱいにするために等しく拡張されますが、残りのテキストボックスは拡張されません。


 下図の2つのフォームは、一組の要素(ボタン、ラベル、テキストボックス)をもつLinearLayoutを表しています。
 うまくパディングを調節するために両方ともパディング値を持っています。これらのテキストボックスの幅はFILL_PARENTに設定されています。(その他の要素はWRAP_CONTENTに設定)
重力(gravity)はデフォルトの左に設定されています。
左側のフォームはweight値が設定されていません(デフォルトの0)。
 一方、右側のフォームはCommentsのテキストボックスのweightに"1"が設定されています。
Nameのテキストボックスにも"1"が設定されたら、NameとCommentsのテキストボックスは同じ高さになります。


ヒント:バランスのとれたレイアウトの画面を作るには、fill_parent属性のコンテナオブジェクトを作成し、子要素にゼロの高さ、または幅を割り当て、各要素が取るべき画面の割合に従った相対的なweight値を各子要素に割り当てます。


 水平のLinearLayoutでは、アイテムはテキストのベースライン{最初のリスト要素の最初のライン(一番上、一番左を基準の線とみなす)}の位置に整列されます。
 これはフォーム要素を目で追う時に隣のテキストを読むために視線が上がったり下がったりしないですむようにするためです。XMLのレイアウトで android:baselineAligned="false" を設定することによって取り消すこともできます。

TableLayout

 TableLayoutは行と列に子要素を配置します。TableLayoutはいくつかのTableRowオブジェクトから成りたっています。
 各々が列(以下に説明されるように他の子要素を持つこともできます)を定義します。
 TableLayoutコンテナは、行、列、セルの境界線は表示しません。各列はゼロ以上のセルを持ちます。
(各セルは一つのViewオブジェクトを持つことができます。)
 テーブルは最も多くのセルを持つ行と同じだけの列を持ち、空のままのセルを持つことができます。
セルはHTMLでできるように列全体に広げるようなことはできません。(訳注:tableタグのcolspan属性のようなことはできない。)
 以下のイメージは、点線で表示されている目に見えないセルの境界線としてテーブルレイアウトを示しています。


 列を隠すこともでき、その列が残り画面スペースを埋めるように指定することができます。
また、テーブルが画面に合うように強制的にその行を縮めるように指定することもできます。
詳細は、このクラスについてのドキュメントを参照してください。

AbsoluteLayout

 AbsoluteLayoutでは、子要素を画面に表示する正確なx/y座標を指定することができます。(0,0)は左上で、右あるいは下に動くことで値が増加します。
 マージンはサポートされておらず、要素が重なることは(お勧めできないが)許容されます。
 融通が利かず、異なるデバイスの画面表示でうまく機能しない為、正当な理由がない限り、通常AbsoluteLayoutを使うことはお勧めできません。

RelativeLayout

 RelativeLayoutでは、子要素にお互い(IDによる指定)の、あるいは親要素との相対的な位置を指定します。
 右端に2つの要素を並べたり、要素の下に要素を置いたり、画面の中央に配置することができます。
 要素は与えられた順序で描画されるので、最初の要素が画面の中央にあるなら、その要素に対して並べられている他の要素は画面の中央と相対的に並べられることになります。
 このレイアウトを指定する為にXMLを使う場合、参照される(基準となる)要素は、それが参照される前にリストされていなければなりません。


 以下の図は目に見える要素と見えない要素を相対的に配置している例を解説しています。
 ルートの画面のレイアウトオブジェクトはRelativeLayoutオブジェクトを使用しています。


 この図は画面構成要素のクラス名とそれぞれのプロパティのリストを表しています。
 これらのプロパティのいくつかは要素によって直接サポートされ、いくつかはLayoutParamsメンバーによってサポートされます(画面のすべての要素のためのRelativeLayoutサブクラスです。なぜなら全ての要素はRelativeLayout親オブジェクトの子要素だからです。)。
 RelativeLayoutパラメータにはwidth、height、below、alignTop、toLeft、padding、marginLeftがあります。 これらのパラメータのいくつかは他の子要素に対する相対的な値をサポートしていることに注意してください。toLeft、alignTop、belowプロパティは、それぞれ、左(toLeft)、上(alignTop)、下(below)にあるオブジェクトを示します。

重要なViewグループのサマリー

 これらのオブジェクトはすべて子UI要素を持ちます。
 いくつかは目に見えるUIを提供しますが、いくつかは子レイアウトを処理するだけです。

Class 説明
AbsoluteLayout 正確な目盛(例えばピクセル)において親オブジェクトに対する相対的な子オブジェクトの位置を指定することができます。
FrameLayout 一つのオブジェクトを表示するViewフレームとして振舞うレイアウトです。
Gallery リストからイメージを水平スクロール表示させます。
GridView m行とn列のスクロールするグリッドを示します。
LinearLayout 水平あるいは垂直の列に子要素を配置するレイアウトです。ウインドウの長さがスクリーンの長さを上回る場合は、スクロールバーを生成します。
ListView スクロールする1列のリストを表示します。
RelativeLayout お互いの要素の相対的な指定(子Bの左へ子等ど)、親要素との相対的な指定(親のトップに整列する等)を用いて、子オブジェクトの位置を指定することができます。
ScrollView 要素を垂直スクロールさせる列です。
Spinner 1行のテキストボックスに、リストから一度に一つのアイテムを表示します。水平、または、垂直にスクロールすることができる1列のリストボックスのようなものです。
SurfaceView 描画専用のsurfaceへの直接アクセスを提供します。surfaceの上のレイヤーになる子Viewを持つことができますが、widgetsを使うよりも、ピクセルで描画する必要があるアプリケーションで使用される事を目的としています。
TabHost タブのクリックを監視して、アプリケーションが画面を変更するのを可能にするタブ選択リストを提供します。
TableLayout 任意の数の行と列を持つ表のレイアウトです。各セルは任意のwidgetを持つ事が出来ます。横列は最大の縦列に合わせてリサイズされます。セルの境界線はありません。
ViewFlipper 1列のテキストボックスに1つのアイテムを表示するリストです。スライドショーのように、時間間隔を設定してアイテム表示を入れ替えることが出来ます。
ViewSwitcher ViewFlipperと同様のものです。