レイアウト(1)-ウィジェット(Viewクラス)の幅と高さと位置


これから、何回かに渡って、ウィジェット(Viewクラス)の配置とレイアウトについてみていく。

レイアウトコンテナ

faviconAndroidでGUI - 愚鈍人」で述べたように、ActivityのContentViewには通常、ViewGroupクラスのサブクラスを配置する。

ViewGroupクラスのサブクラスはレイアウトと呼ばれ、以下のようなクラスが存在する。

それぞれのレイアウトクラスには、その内部にウィジェットを配置するためのクラスとして、 以下のようなViewGroup.LayoutParamsを継承した各レイアウト専用のLayoutParamsクラスが用意されていて、 基本的には、この専用のLayoutParamsクラスを使ってウィジェットを配置する。

  • LinearLayout.LayoutParamsクラス
  • FrameLayout.LayoutParamsクラス
  • RelativeLayout.LayoutParamsクラス
  • TableLayout.LayoutParamsクラス

 

レイアウトについての参考サイトを以下に列挙しておく。

LinearLayout

LinearLayoutについては、「faviconAndroidでGUI - 愚鈍人」でも軽くふれているので、 ここでは参考URLのみを示す。

LinearLayoutのxml属性については 「faviconUIコンポーネント/LinearLayout - Android Wiki*」 が参照になる。

LinearLayout.LayoutParamsのxml属性については 「faviconUIコンポーネント/LinearLayout.LayoutParams - Android Wiki*」 が参照になる。

 

レイアウトクラスとしてLinearLayoutを使うものとして、以降、ウィジェットの配置について考えてみる。

幅と高さの指定

xmlレイアウトファイルにおいて、ウィジェットの幅と高さを指定するにはlayout_width属性とlayout_height属性を使う。

この属性の値には、以下のような値を指定する。

  • wrap_content
    ウィジェットの領域を適当に調整して配置。
  • fill_parent
    残っている領域すべて使って配置。
  • 単位付きの数値を指定
    指定できる単位には、後述のDimensionと同じものが使えるようだ。

《追記》

fill_parentは「API Level 8(Android2.2)」から非推奨になっていて、 代わりにmatch_parentを使う事が推奨されています。

match_parentとfill_parentは同じ値(-1)が定義されていて同じ動作をしますが、 今後はmatch_parentを使うようにした方が良いようです。

 

以下に、その例を示す。

リスト1-layout_width属性,layout_height属性の例(main.xml)

最初のボタンは幅,高さともにwrap_contentを指定されているので、 text属性に指定した「wrap_content」という文字を表示できるように、 適当な幅と高さに調整されて配置される。

2番目のボタンは指定された数値の大きさ,幅200ピクセル,高さ100ピクセルで配置される。

3番目のボタンは幅,高さともにfill_parentが指定されているので、 親ウィジェット(LinearLayout)の残りすべての領域を使って配置される。

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

 

 

Dimension

リソースファイル(res/valuesデレクトリ)にDimensionと呼ばれる値を定義して、そのDimensionの名前を使って間接的に layout_width属性,layout_height属性の値を指定する事もできる。

以下は、Dimensionを使ってリスト1の2番目のボタンの幅と高さを指定する例である。

リスト2(1)-リソースファイルにDimensionを定義(dimension.xml)

リスト2(2)-リスト1を修正,2番目のButton部分のみを抜粋(GraphicsSample1.java)

Dimensionで指定できる数値の単位には、dp,sp,pt,px,mm,inが使える

詳しくは、 「favicon7.5.8 その他のリソースタイプ - ソフトウェア技術ドキュメントを勝手に翻訳」 , 「Y.A.M の 雑記帳: Android Dimension 単位」 を参照。

幅と高さをコードで指定

リスト1のレイアウトファイルをコードで置き換えると、以下のようになる。

リスト3-幅と高さをコードで指定-(LayoutSample1Activity.java)

幅と高さを数値で指定する場合(29行目)には、ピクセル単位でのみ指定可能なようである。

addViewメソッドにはオーバロードされたメソッドがあり、 LayoutParamsクラスのインスタンスを作成せずに、 直接addViewメソッドの引数に幅と高さの値を指定しても良い。

リスト4-リスト3を修正して、addViewメソッドの引数に幅と高さの値を指定

また、ウィジェットはLayoutParamsオブジェクトを内部に保持しており、 View#setLayoutParamsメソッドを使って、ウィジェットに対して直接、幅と高さを指定する事もできる。

リスト5-ウィジェットに対して直接、幅と高さを指定

View#setLayoutParamsメソッドで設定したLayoutParamsオブジェクトは、 View#getLayoutParamsメソッドを使って取得する事もできる。

setLayoutParamsメソッドとaddViewメソッドで異なる幅と高さを指定した場合には、 後で指定した値が優先されるようだ。

ウィジェットの幅と高さにどのような値が設定されているかは、 View#getWidthメソッドとView#getHeightメソッドを使って知る事ができる。

しかし、onCreateメソッドやonResumeメソッド等でウィジェットを配置中にこのメソッドを実行しても、 値が確定していないので正しい値を得る事はできない。

以下は、リスト3のプログラムを変更して、buton1が押された時にbuttonの幅と高さをLogに表示するコードを追加する例である。

リスト6-buton1が押された時にbuttonの幅と高さをLogに表示するコードを追加

どうでもいい話であるが、「width」と「height」は「ウィズ」と「ハイト」と読むらしい。

faviconwidthとheightの読み方 - 130単位」を参照。

位置の取得

Androidでは、基本的にはウィジェットを配置する位置を座標で自由に指定する事ができない。

ウィジェットの位置は、各レイアウトによって決められたルールに従って、配置される事になる。

これは、解像度が異なるさまざまなハードウェアに対応できるようにするためのようだ。

VisualBASIC等のWindowsアプリ系の開発ツールに慣れている方には、違和感を感じてしまう点である。

(「AndroidのViewの配置ってVisualStudioみたいにドラッグで表示位置を調整できないの? | mucchinのAndroid戦記」 を参照。)

しかし、マージンを設定する事で、間接的に配置位置を調整する事はできる。

(「faviconレイアウト(3)-ウィジェットのパディングとマージン - 愚鈍人」 を参照。)

 

ウィジェットがどの位置に配置されているかは、Viewクラスのメソッドを使って知る事ができる。

メソッド 動作
getLeftメソッド ウィジェットの左端の親ウィジェットからの相対位置を取得する。
getTopメソッド ウィジェットの上端の親ウィジェットからの相対位置を取得する。
getRightメソッド ウィジェットの右端の親ウィジェットからの相対位置を取得する。
getBottomメソッド ウィジェットの下端の親ウィジェットからの相対位置を取得する。
getLocationInWindowメソッド 画面(Window)右上端からのウィジェットの右上端の位置を取得する。
getLocationOnScreenメソッド 画面(Screen)右上端からのウィジェットの右上端の位置を取得する。

getLocationInWindow、getLocationOnScreenメソッドが、 タイトルバー等も含めた画面左上部からの絶対座標を返すのに対して、 他の4つのメソッドは親ウィジェットからの相対座標を返す。

getLocationInWindowとgetLocationOnScreenのWindowとScreenの違いというのが、 何を意味しているのかよくわからない。

以下は、リスト6を変更して、 buton2が押された時にbuttonの座標位置をLogに表示するプログラムの例である。

リスト7-buttonの座標位置をLogに表示

その他

Viewクラスについては、以下のページが参考になりそう。

ウィジェットの描画のされ方については、以下のページが参考になりそう。

 

ページのトップへ戻る