レイアウト(9)-RelativeLayout(相対的位置にウィジェットの配置)をマスターする。


RelativeLayoutは、名前のとおり相対的にウィジェットの配置をおこなうレイアウトである。

このレイアウトを調べていて、相対位置を指定するパラメータがいろいろとあって、違いを把握するのに苦労してしまった。

パラメータはいろいろとあるのだが、「何に対して相対的なのか?」,「上下の位置関係は?」,「左右の位置関係は?」 を、分類してみるとわかりやすくなるように思う。

親ウィジェットに対する相対位置を指定する

以下のパラメータを使って、親ウィジェットに対する相対位置を指定して、ウィジェットの配置をおこなうことができる。

横軸の位置を指定するパラメーター。

  • 左側に配置:layout_alignParentLeft
  • 中央に配置:layout_centerHorizontal
  • 右側に配置:layout_alignParentRight

縦軸の位置を指定するパラメーター。

  • 上側に配置:layout_alignParentTop
  • 中央に配置:layout_centerVertical
  • 下側に配置:layout_alignParentBottom

横軸,縦軸ともに中央に配置するパラメータ。

  • 横軸,縦軸ともに中央に配置:layout_centerInParent
    これは一つのパラメータで、横軸にcenterHorizontalを縦軸をlayout_centerVertical指定したのと 同じ効果を持つと思われる。

 

これらのパラメーターには、値としてtrueを指定する。

以下に、これらの各パラメータを組み合わせたxmlレイアウトファイルの例を示す。

リスト1-親ウィジェットに対する相対位置を指定するレイアウトファイルの例(main.xml)

このプログラムを実行すると、以下のような画面が表示される。

 

 

子ウィジェットに対する相対位置を指定

他のRelativeLayoutの子ウィジェットに対する相対位置を指定して、ウィジェットの配置をおこなうことができる。

子ウィジェットの外側に配置するパラメータと、内接する位置に配置するパラメータとがある。

パラメーターの値として、対象となる子ウィジェットのIDを指定する。

(1)子ウィジェットの外側(となり)に配置するパラメータ

以下のパラメータを使って、他の子ウィジェットに隣接する位置を指定して、ウィジェットの配置をおこなうことができる。

横軸の位置を指定するパラメーター。

  • 左側に配置:layout_toLeftOf
  • 右側に配置:layout_toRightOf

縦軸の位置を指定するパラメーター。

  • 上側に配置:layout_above
  • 下側に配置:layout_below

以下に、これらの各パラメータを組み合わせたxmlレイアウトファイルの例を示す。

リスト2-他の子ウィジェットのとなりに配置するレイアウトファイルの例(main.xml)

このプログラムを実行すると、以下のような画面が表示される。

 

 

(2)他の子ウィジェットの内側(内接する位置)に配置するパラメータ

これは、他の子ウィジェットのどちらか片側と同じ位置に、ウィジェットを整列するように配置するパラメータである。

以下のパラメータを使って、他のウィジェットに内接する位置に、ウィジェットの配置をおこなうことができる。

横軸の位置を指定するパラメーター。

  • 左側に配置:layout_alignLeft
  • 右側に配置:layout_alignTop

縦軸の位置を指定するパラメーター。

  • 上側に配置:layout_alignTop
  • 下側に配置:layout_alignBottom

以下に、これらの各パラメータを組み合わせたxmlレイアウトファイルの例を示す。

リスト3-他の子ウィジェットに内接する位置に配置するレイアウトファイルの例(main.xml)

このプログラムを実行すると、以下のような画面が表示される。

 

 

ウィジェットを等間隔に整列させる

(1)と(2)のパラメータを組み合わせる事によって、 基準のウィジェットに対して等間隔で一列に整列させる事ができる。

以下は、親ウィジェットの中央に配置したボタンを基準に、 下方向に等間隔で縦一列にウィジェットを整列させた例である。

リスト4-他の子ウィジェットを基準に等間隔でウィジェット整列させる(main.xml)

このプログラムを実行すると、以下のような画面が表示される。

 

 

layout_alignBaseline-他の子ウィジェットにベースラインの位置を合わせる

layout_alignBaselineを指定すると、 テキストのベースラインの位置を他の子ウィジェットのベースラインの位置に合わせるように、 ウィジェットを配置する事ができる。

以下は、親ウィジェットの中央に配置したボタンを基準に、ベースラインの位置に合わせて左右に ボタンを配置する例である。

リスト5-他の子ウィジェットのベースラインの位置に合わせて左右にボタンを配置する(main.xml)

このプログラムを実行すると、以下のような画面が表示される。

 

 

layout_alignWithParentIfMissing

layout_alignWithParentIfMissingパラメータをtrueに指定すると、 相対位置の基準となる他の子ウィジェットが見つからない場合に、親ウィジェットを基準にして配置をおこなう。

以下の例は、リスト3の例を変更して、各ウィジェットにlayout_alignWithParentIfMissingパラメータを 追加するとともに、基準となるウィジェットを非表示(visibility属性をgoneに設定)にした場合の例である。

リスト6(main.xml)

このプログラムを実行すると、以下のような画面が表示される。

 

 

同じように、以下のようにリスト2の例を変更してlayout_alignWithParentIfMissingパラメータ指定すると、 面白いことに、親ウィジェットの外側にはみ出した位置のウィジェットが表示される。

リスト7(main.xml)

 

 

親ウィジェットに対する相対位置と子ウィジェットに対する相対位置の混在指定

以下のように、横軸,縦軸どちらか一方を親ウィジェットに対する相対位置に、 もう片方を子ウィジェットに対する相対位置に指定する事も可能である。

コードを使ってRelativeLayoutを記述する。

以下のレイアウトファイルは、RelativeLayoutの内部にButtonを3個を配置した例である。

リスト8(main.xml)

これを、レイアウトファイルを使わずにコードで実現すると、以下のようになる。

リスト9-コードを使ってRelativeLayoutを記述(RelativeLayout2Activity.java)

相対位置を指定するパラメータをコードで記述する場合は、 RelativeLayout.LayoutParams#addRuleメソッドを使う。

addRuleメソッドの引数には、xml属性に対応するRelativeLayoutクラスで定義されている定数を指定する。

これまでのまとめも含めて、xml属性に指定するパラメータとaddRuleメソッドの引数に指定する定数の対応表を以下に示す。

対象 相対位置 xml属性 定数名 定数値
横軸,縦軸ともに中央 layout_centerInParent CENTER_IN_PARENT 13
横軸 layout_alignParentLeft ALIGN_PARENT_LEFT 9
横軸 layout_centerHorizontal CENTER_HORIZONTAL 14
横軸 layout_alignParentRight ALIGN_PARENT_RIGHT 11
縦軸 layout_alignParentTop ALIGN_PARENT_TOP 10
縦軸 layout_centerVertical CENTER_VERTICAL 15
縦軸 layout_alignParentBottom ALIGN_PARENT_BOTTOM 12
隣接 横軸 layout_toLeftOf LEFT_OF 0
横軸 layout_toRightOf RIGHT_OF 1
縦軸 layout_above ABOVE 2
縦軸 layout_below BELOW 3
内接 横軸 layout_alignLeft ALIGN_LEFT 5
横軸 layout_alignRight ALIGN_RIGHT 7
縦軸 layout_alignTop ALIGN_TOP 6
縦軸 layout_alignBottom ALIGN_BOTTOM 8
その他 横軸 layout_alignBaseline ALIGN_BASELINE 4
- - layout_alignWithParentIfMissing 該当なし -

layout_alignWithParentIfMissingに対応する定数は存在しない。

layout_alignWithParentIfMissingをコードで指定する場合は、addRuleメソッドを使うのでは無く LayoutParamsクラスのインスタンス変数alignWithParentを、直接操作するようだ。

ウィジェットにどのパラメータが設定されているかは、getRulesメソッドで知る事ができる。

getRulesメソッドは、int型の16個の要素を持つ配列を返す。

パラメータの値がこの配列にどのように格納されているかは、リスト9(19行目のshowRuleメソッドを参照)を実行した結果のLogをみれば、 推察できる。

 

 

例えば、button3のlayout_alignLeftパラメータの値が知りたいのであれば、 ALIGN_LEFT定数の値が5なので配列の添え字が5の要素の値を参照すると、 idが2のウィジェット(button2)が指定されていることがわかる。

値をtrueで指定するパラメータの場合は-1(RelativeLayout.TRUE定数で定義されている)が格納される。

RelativeLayout.TRUE定数を使うと、リスト9の23行目のコードは以下のように記述することもできる。

これらの値が0の場合は未指定となる。

button1のlayout_centerInParentと、button2のlayout_centerHorizontal,layout_centerVerticalの 組み合わせは、ともに中央に配置されるが異なる値として格納されている事がわかる。

その他のトピック

RelativeLayoutとGravity

RelativeLayoutにGravity属性を指定する事もできる。

以下のように、リスト4のレイアウトファイルのRelativeLayoutにGravity属性を追加する。

リスト10(main.xml)

Gravityなしの画面とありの画面を比較すると、以下のようになる。

 

リスト4-Gravityなし リスト10-Gravity属性を右下に設定

 

しかし、リスト1の画面のように親ウィジェット内いっぱいにウィジェットが存在する場合にはGravityの効果はなくなるようだ。

ignoreGravity

Gravity属性を無視するウィジェットのIDを指定。

faviconUIコンポーネント/RelativeLayout - Android Wiki*」を参照。

RelativeLayoutとmargin

RelativeLayout.LayoutParamsクラスもMarginLayoutParamsを継承していて、marginを設定できる。

marginを使うと、ウィジェット間の間隔を調整することができる。

以下は、リスト4のレイアウトファイルを修正して、ウィジェット間の間隔を50ピクセル分広く設定した例である。

リスト11-リスト4のウィジェット間の間隔を50ピクセル分広く設定(main.xml)

このプログラムを実行すると、以下のような画面が表示される。

 

 

しかし、以下の例のようにmargin属性の指定の仕方によっては、予想外の配置のされ方をしてしまうようだ。

リスト12-リスト2のレイアウトファイルにmargin属性を追加(main.xml)

このプログラムを実行すると、以下のような画面が表示される。

 

 

参考URL

 

ページのトップへ戻る