レイアウト(7)-FrameLayout ウィジェットを重ね合わせて配置する。
FrameLayout
FrameLayoutは、後に配置したウィジェットが先に配置したウィジェットの上に重ね合わせて表示される。
透過色を使って背景画像に上書きする形で、 下のレイヤーから上のレイヤーまで何階層かに渡って画像を合成して表示させるのに便利かな。
次の例は、FrameLayoutを使って大きさの異なるボタンを重ね合わせて表示する、xmlレイアウトファイルの例である。
このプログラムを実行すると、以下のような画面が表示される。
FrameLayoutの内部に最初に配置したbutton1ボタンが最背面に、 2つ目に配置したbutton2ボタンがbutton1ボタンの前面に、 最後に配置したbutton3ボタンが更にbutton2ボタンの前面にと、 後に配置したウィジェットほど前面に表示されているのがわかる。
動的にウィジェットの重ね合わせの順番を変更する。
FrameLayoutの表示順は、先に追加されたウィジェットほど下層のレイヤーに表示されるので、 この追加順を変更してやる事で動的にウィジェットの重ね合わせの順番を変更する事ができる。
これには、ViewGroupクラスのremoveViewメソッドとaddViewメソッドを使う。
addViewメソッドは、レイアウトにウィジェットを追加する時におなじみのメソッドであるが、 追加位置を指定するオーバロードされたメソッドも存在する、このメソッドを使う。(「レイアウト(8)-Viewの階層構造をあやつる - 愚鈍人」も参照。)
表示順(位置)を変更したいウィジェットを、一旦、removeViewメソッドを使ってFrameLayoutから削除した後、 addViewメソッドを使って挿入位置を指定して、再度、削除したウィジェットを追加してやる。
以下は、リスト1のレイアウトファイルの3つのButtonに対して、 Buttonが押下された時に押下されたButtonを最背面に移動させるプログラムの例である。
リスト2(FreamLayut1Activity.java)
このプログラムを実行して、Buttonを押下すると、押下されたButtonが最下層(最背面)に移動する。
FrameLayoutとGravity
「レイアウト(4)-Gravity ウィジェットを片方向に寄せる - 愚鈍人」 では、レイアウトにGravityを指定する事でウィジェットを片方向に寄せて配置できると述べたが、 FrameLayoutにGravityを指定しても何も変化しないようだ。
例えば、以下のようにリスト1を修正して、6行目にGravityの指定行を追加してもbuttonは下方に移動しない。
しかし、Gravityがまったく使えないのかというと、そうでもない。
FrameLayout内部に配置したウィジェットに対して、個々にlayout_gravity属性を指定すればよい。
例えばリスト1を以下のように修正して、 button2を下方向に,button3を右方向にlayout_gravity属性を指定する。
このプログラムを実行すると、意図した方向にbuttonが移動しているのがわかる。
FrameLayoutとマージン
FrameLayoutの内部に配置するウィジェットにマージンを設定する事で、 表示位置が重ならないように位置をずらすことができる。( マージンについては「レイアウト(3)-ウィジェットのパディングとマージン - 愚鈍人」を参照)
リスト4のレイアウトファイルを以下のように修正する。
このプログラムを実行すると、以下のような画面が表示される。
指定したマージンの値が、Buttonの位置に反映されているのがわかる。
ただし、注意すべき点として、FrameLayoutのマージンはlayout_gravityの指定が無いと有効にならないようだ。
layout_gravityがデフォルトではtop|leftで指定されているはずだからと思って、リスト5の11行目のlayout_gravityの指定を削除してしまうと、 button1はマージンで指定された位置に移動しなくなる。
foreground属性とforegroundGravity属性 - 最前面に更に画像を表示
foreground属性を指定して、子ウィジェットの更に前面(最前面)に画像を表示させる事ができる。
また、foregroundGravity属性を指定して、foreground属性に指定した画像のGravityを指定する事ができる。
勘違いしやすい点であるが、foregroundGravity属性は、foregroundに指定した画像に対するGravityの指定であって、 子ウィジェットに対するGravityの指定ではないようなので注意。
リスト5のレイアウトファイルのFrameLayoutの部分を、 以下のように修正して foreground属性とforegroundGravity属性を確認してみる。
修正したレイアウトファイルを使って画面を表示してみると、以下のようなる。
foreground属性とforegroundGravity属性の指定により、アイコン画像が右側中央に表示されるのがわかる。
ちなみに、foregroundGravity属性はデフォルトでfillとなっており、指定しない場合、アイコン画像は画面一杯に拡大されて表示される。
FrameLayoutをコードで記述
リスト5,6のレイアウトを、レイアウトファイルを使わずにコードを使って記述すると、以下のようになる。
リスト7(FreamLayut2Activity.java)
参考URL
FrameLayoutのxml属性については、以下のページが参考になるかも。
-
UIコンポーネント/FrameLayout - Android Wiki*
FrameLayoutのxml属性についてまとめられている。 -
UIコンポーネント/FrameLayout.LayoutParams - Android Wiki*
FrameLayoutクラスのxml属性についてまとめられている。