レイアウトの宣言

この章は、親なのか子なのかが入り組んでいて、ややこしかったです。
原文: http://developer.android.com/guide/topics/ui/declaring-layout.html

                                                                                                              • -

レイアウトとは、Activity(アクティビティ)が保持するユーザインターフェース構造を表しています。UIの配置構成やユーザに表示する全ての要素を保持しています。レイアウトは以下の2種類の方法で定義することができます。

  • XMLでUIの要素を定義する

Androidでは、View(ビュー)クラスと、ウィジェットやレイアウトのようなViewクラスのサブクラスを処理するわかりやすいXML言語を提供しています。

  • ランタイムでレイアウト要素を生成する。

ソースコード上でViewとViewGroup(ビューグループ)オブジェクトを生成し、そのプロパティを操作することができます。

Androidフレームワークでは、アプリケーションのUIを開発するために、上記の方法のどちらか、または両方を使えるように柔軟性を持たせています。例えば、デフォルトのレイアウトはXMLで定義しておいて、実行時に画面に表示するオブジェクト(XMLで定義したレイアウト要素も含む)を変更するようなソースコードを記述することも可能です。

XMLでUIを定義することの利点は、アプリケーションのプレゼンテーション処理を、振る舞いを制御するコードから分離できることです。UIの記述がソースコードから分離されているので、ソースコードの修正や再コンパイルをせずにUIを修正することができます。異なる画面環境、異なる画面サイズ、異なる言語ごとにXMLレイアウトを作成することも可能です。加えて、XMLでレイアウトを宣言すれば、UI構造の可視化が容易になり、プログラムをデバッグしやすくなります。そのようなことから、本ドキュメントでは、XMLでレイアウトを定義する方法に焦点を当てて解説します。実行時にViewオブジェクトを生成する方法については、ViewGroupとViewクラスのリファレンスを参照してください。

一般的に、UIのエレメントを宣言するXMLの語句は、クラスやメソッドのネーミングルール及び構造にほぼ準拠しており、エレメント名がクラス名、属性名がメソッド名に対応しています。この対応関係はとても直感的ですので、エレメントに対応するクラスや、属性に対応するメソッドを推測することができます。しかしながら、全ての語句が完全にこのルールに従ってはいないことに注意してください。ごく稀に若干ネーミングルールが違う場合があります。例えば、EditTextエレメントはtext属性を持っていますが、対応するメソッドはEditText.setText()です。


「一般的なレイアウトオブジェクト」では、様々なレイアウトタイプを学習することができます。開発チュートリアルとして、「Hello Views」もあります。

EclipseAndroid Development Tools(ADT)プラグインでは、XMLのレイアウトプレビューを提供しています。XMLファイルを開いて、レイアウトタブを選択してみてください。
レイアウトのデバッグ時には、Hierarchy Viewerツールも試してみてください。エミュレータや端末上でデバッグ中にレイアウトのプロパティ値が表示されるだけでなく、パディング/マージンの指標が付いたワイヤフレームの描画や、レンダリング済のViewの表示もサポートします。


【ページ内目次】

XMLの記述
Androidでは、XMLを利用してUIのレイアウトと画面エレメントを素早く設計することができます。入れ子構造のエレメントを利用して、HTMLのウェブページを作成することもできます。

各レイアウトファイルには、ルートエレメントを必ず1つ含めなければなりません。ルートエレメントはViewかViewGroupでなければなりません。ルートエレメントを定義した後は、子エレメントとしてレイアウトオブジェクトやウィジェットを追加し、徐々にView階層を組み立てていきます。以下は、TextViewとButtonを保持する LinearLayoutを使ったXMLレイアウトの例です。


    
    


XMLでレイアウトを定義後、Androidプロジェクトのres/layoutディレクトリに拡張子が.xmlのファイルを保存すれば、適切にコンパイルされます。

各属性については、後ほど解説します。


APIリファレンスドキュメントのUI関連のクラスには、クラスのメソッドに対応するXML属性がリスト化されています。利用可能なXMLのエレメントや属性に加え、XMLファイルのフォーマットについての詳細は、「レイアウトリソース」を参照してください。

XMLリソースのロード
アプリケーションのコンパイル時に、各XMLレイアウトファイルもコンパイルされ、Viewリソース内に配置されます。コンパイルされたレイアウトリソースは、Activity.onCreate()コールバックメソッドでロードしてください。setCotentView()を呼び出して、引数にレイアウトリソースの参照をR.layout.の形式で渡します。例えば、XMLレイアウトをmain_layout.xmlで保存した場合、以下のようになります。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView.(R.layout.main_layout);
}


ActivityのonCreate()コールバックメソッドは、Activityが起動されたときに、Androidフレームワークによって呼び出されます(詳細は、「アプリケーションの基礎」のライフサイクルを参照してください)。

属性
各ViewとViewGroupは、様々なXML属性をサポートしています。特定のViewオブジェクトに特化した属性(例えばTextViewがtextsize属性をサポートしているなど)は、Viewクラスの拡張クラスで定義されている属性です。全てのViewオブジェクトで共通の属性もありますが(id属性など)、これはルートのViewクラスで定義されている属性です。その他に、”レイアウトパラメータ”属性も存在します。これは、Viewオブジェクトの親にあたるViewGroupによって定義されている属性で、Viewオブジェクトのレイアウトを決定付ける属性です。

ID
どんなViewオブジェクトでも、ツリー内のViewを一意に識別することができるIDを持っています。アプリケーションコンパイル時に、このIDはInteger型として参照されますが、XMLレイアウトファイルでは多くの場合、String型として割り当てられています。IDは、すべてのViewオブジェクトで共通のXML属性であり、頻繁に使われます。ID体系に関しては、以下のXMLタグを見てください。

android:id="@+id/my_button"


文字列の最初にあるアットマーク記号(@)は、XMLパーサが@以下の文字列をリソースIDとして解析すべきであることを示しています。プラス記号(+)は、リソース(R.javaファイル内)に新規に追加する名前であることを意味しています。ちなみに、Androidフレームワークでは様々なリソースIDを標準で提供しており、このAndroidリソースIDを参照する際にはプラス記号は必要なく、代わりに以下のようにandroidパッケージのネームスペースを追記しなければなりません。

android:id="@android:id/empty"


上記は、ローカルリソースクラスを参照する代わりに、androidパッケージのネームスペースを使ってandroid.RリソースクラスからIDを参照しています。


Viewを作成し、アプリケーションからViewを参照する一般的な方法を以下に示します。

1. レイアウトファイル内にViewまたはウィジェットを定義し、それにユニークIDを割り当てる。


2. レイアウトのIDを利用して、Viewオブジェクトのインスタンスを取得する(一般的にはonCreate()メソッドで取得する場合が多い)。

Button myButton = (Button) findViewById(R.id.my_button);


ViewオブジェクトのID定義は、RelativeLayout(相対レイアウト)を作成する際に重要になります。相対レイアウトでは、ユニークなIDを利用して、あるViewが関連する別の兄弟Viewのレイアウトを定義できるからです。

IDはツリー全体を通してユニークにする必要はありませんが、検索を実行したい部分はユニークにすべきです(ツリー全体を検索する場合もあるので、可能であればツリー全体を通して完全にユニークにするのがベストな方法です)。

レイアウトパラメータ
layout_somethingという名前のXMLレイアウト属性はViewのレイアウトを定義するものであり、自分の親に当たるViewGroupによって定義する内容が決められます。

各ViewGroupクラスでは、ViewGroup.LayoutParamsを拡張したクラスを保持しています。このサブクラスは、自分の子Viewのサイズや位置を定義するプロパティを保持しています。つまり、下記の図のように、親であるViewGroupが子であるView(ViewGroupも含む)のレイアウトパラメータを保持しています。


LayoutParamsのサブクラスごとに、値をセットする方法が異なることに注意してください。子であるViewがそれぞれ異なるLayoutParamsクラスを定義するような場合であったとしても、子Viewはその親にとって適切なLayoutParamsを判断して設定しなければなりません。

すべてのViewGroupは幅と高さ(layout_width, layout_height)を保持しており、各Viewがそれらを定義しなければなりません。また、多くのLayoutParamsが任意項目としてマージンやボーダーを保持しているため、あまりやりたくはないでしょうが、正確なViewの大きさを自分で定義することができます。ただ、多くの場合は、Viewの表示内容に合わせたサイズにするか、親であるViewGroupと同じ大きさにするかのどちらかでしょう(前者はwrap_content, 後者はfill_parentを使います)。設定可能な項目は「利用可能なリソース」ドキュメントで定義されています。

レイアウト位置
Viewの形状は四角形です。Viewは位置情報(左端と上端の座標)と、サイズ情報(高さ、幅)を保持しています。位置とサイズはピクセル指定です。

getLeft(), getTop()メソッドを実行し、位置情報を取得することも可能です。前者の戻り値は四角形の左端のX座標です。後者は四角形の上端のY座標です。このメソッドはどちらも、親オブジェクトからの相対位置を返します。例えば、getLeft()が20を返したとしたら、それは親オブジェクトの左端から右へ20ピクセル進んだ位置にいることを意味しています。

加えて、不要な計算を避けるために、getRight()とgetBottom()メソッドも提供されています。前者は四角形の右端、後者は下端の位置を返します。例えば、getRight()の戻り値は以下の計算式の結果とほぼ同じ値となります。
getLeft() + getWidth()

サイズ、パディング、マージン
Viewのサイズは幅と高さで表現されます。実際には、Viewは幅と高さのペアを2つ保持しています。

最初のペアは、measured widthとmeasured heightです。このサイズ指定では、自分の親に対してどのぐらいの大きさにするかを定義します。getMeasuredWidth()とgetMeasuredHeight()で取得することができます。

2番目のペアは単純に、widthとheightです。drawing width、drawing heightとも呼ばれます。このサイズ指定は、描画時に描画される画面上の実際のViewサイズです。このサイズは、そうする必要性はないものの、measured widthやmesured heightとは異なる値にすることもできます。widthとheightはそれぞれgetWidth()とgetHeight()で取得することができます。

サイズを計算する際、Viewはパディングも考慮に入れます。パディングは、Viewの左、上、右、下に対してピクセルで指定できます。パディングは指定されたピクセル数だけ、Viewを余白で埋めてくれます。例えば左のパディングが2であれば、左端から2ピクセル右に進んだ位置からViewの内容が表示されます。パディングはsetPadding(int, int, int, int)メソッドで定義され、getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom()で取得できます。

Viewは、パディングはサポートしますが、マージンはサポートしません。ただし、ViewGroupではマージンをサポートしています。詳細は、ViewGroupとViewGroup.MarginLayoutParamsを参照してください。

サイズに関する詳細は、「サイズ指定」を参照してください。

                                                                                                                        • -


Android翻訳目次へ