× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。 |
Androidで、ビューをpx指定で表示したいことがある。
当たり前のやり方のような気がするが、意外と方法が用意されていない。 iOSなら、view.frameやview.boundsで矩形を指定することができるのだが、Androidはそれがない。 Androidは、ビューに加えて、レイアウト(FrameLayout,LinearLayout,RelativeLayoutなど)という概念がある。 (正確にはレイアウトもビューなのだが。) ビューはレイアウトの中に配置される。 そのビューを、レイアウトから上下左右のマージンいくつ離すか、という指定をすることになる。 本来これでいいはずなのだが、 実際にビューを配置してみると、狙った位置と大きさも位置もずれていることがある。 なぜか。 マージンを指定することによって、矩形の大きさが決まる。 例えば、幅640,高さ240のLayoutの中に、左右マージン各20,上下マージン各10を取ると、 ビューのRect(x,y,w,h)=(20,10,600,220)になる。 しかし、ビューが実際に正確にその大きさで配置されるとは限らない。 たとえば、ビューの幅、高さの指定がWRAP_CONTENTだと、矩形のサイズはあまり関係なくビューの「見た目の大きさ」は決まってしまう。 また、MATCH_PARENTだとしても、 たとえばImageViewなら、元画像の縦横比を崩さない範囲で最大サイズ表示、のようなことになるからだ。 また、広告SDKで表示するアイコンなど、実際の表示サイズが不定になるものの場合もある。 そのようなとき、ビューは大抵左上寄せの位置に表示される。 これは嫌だ。指定座標を中心とする位置に収まってほしい。 じゃあ、gravityをCENTERに指定すれば…? としたいが、gravity指定はビューにはできず、Layoutに指定する。 gravityは、そのレイアウト全体の重力場を指定するためのものだからだ。 ビューを中央寄せにする指定をビュー自体に対してできないか…となる。 もちろんその指定はあって、xmlでいうと centerHorizontal などの指定がそれにあたる。これは、 「自分の親のレイアウトの左右方向中心に配置」 ということだ。 ……ということは、自分の親のレイアウトが必要になる。 何も考えずそのままcenterHorizontal,centerVerticalを指定したら、大本のレイアウト(おそらく画面全体を覆うRelativeLayoutになっているだろう)の中心に行ってしまう。それはスクリーンの中心だ。 そうじゃない。 さっき指定した矩形の中心にいてほしいのだ! …………ということは、さっきの指定の矩形のレイアウトを作成すればいいんだ。
という二重構造にすればよい。
こういう感じになる。 中間レイアウトはRelativeLayoutでなければダメで、他のレイアウトだとマージン指定が効かない。 FrameLayoutやLinearLayoutにすると表示位置が左上固定になってしまう。 RelativeLayoutなので、レイアウトパラメータもRelativeLayout.LayoutParamsにする。 ビューのレイアウトパラメータもRelativeLayout.LayoutParamsにする。 でないとaddRule()メソッドが使えない。(だからCENTER_HORIZONTAL/VERTICAL指定ができない) FrameLayoutには lp2.gravity = Gravity.CENTER; のような指定もできるが、これは自分の子孫に対して効かせるパラメータなので、ビュー自身を中央寄せしたい場合は意味が無い。 というわけで、 ================================= 中間レイアウトはRelativeLayout 中間レイアウトのパラメータはRelativeLayout.LayoutParams ビューのパラメータもRelativeLayout.LayoutParams ================================= となる。 ちなみにレイアウトパラメータ類の子孫関係は以下
どのレイアウトパラメータも、コンストラクタの基本はwidthとheightの指定(int)である。 lp1のように、幅と高さを直に設定することもできるが、 多くの場合はlp2のように MATCH_PARENT(-1) か WRAP_CONTENT(-2) という特殊な値を入れて使うことになる。 PR |
|