読者です 読者をやめる 読者になる 読者になる

FLYING

〈全日本・紀文豆乳飲料シリーズ「麦芽コーヒー」の500ミリリットルパックを扱う小売店が少ないことに遺憾の意を表明する会〉活動記録

カスタムViewの例

ここしばらくのAndroid開発で身に付いた,カスタムViewについてのノウハウを軽くまとめておく。

onMeasure/onLayoutについて

ビューが画面に表示される際に,onMeasureとonLayoutが呼ばれるので,そこをいい感じにoverrideしてやるのがポイント。ちなみに,onMeasureはビュー及び子ビューのサイズを決定するために,onLayoutは子ビューの表示領域を決定するために呼ばれる。onMeasureもonLayoutも,ルートビューから子孫ビューに向かってレイアウトツリーを辿るようにして呼ばれる。

onMeasureに関しては,すべての子孫ビューのレイアウトを自身で制御する*1ならば真面目にoverrideする必要はないみたい。ただし,子孫ビューにうんたらLayout*2みたいなViewGroupのサブクラスを含み,なおかつ,うんたらLayoutにその子孫ビューのレイアウトを任せる場合は,onMeasureを真面目に実装しておく必要がある。うんたらLayoutはmeasureメソッドで与えられたMeasureSpec(とLayoutParams)に従い,自身の領域とその子ビューの領域を決定する仕組みになっているようだ。

onMeasure/measureの引数であるMeasureSpecは,ひとつのintに「長さ」と「フラグ」を詰め込んだ特殊な値である。フラグにはEXACTLY・AT_MOST・UNSPECIFIEDがあり,それぞれ「与えられた長さに厳密に従え」「与えられた長さ以下の値ならOK」「好きな長さにしていいよ」という意味を持つ。(本来は)これらのフラグの種別によって,自身のsetMeasuredDimentionメソッドに与える長さや,子ビューに与えるMeasureSpecの値を適切に定めなければならない(が,ここではそこまで真面目な実装はしていない)。

うんたらLayoutのようなクラスは,そのままonMeasureやonLayoutの実装例になっているので,Google謹製のソースを読んでみるのもまた一興。

LazyIconViewの紹介

AndroidのカスタムViewはこんな感じで作ればとりあえず動く,という例のようなクラスをひとつ紹介してみようと思う。正方形の画像をURLから読み込んで影を付けて表示するViewで,ロードが完了するまではProgressBarを表示するというもの。

┌───┬─┐
│   │ │
│   │ │
│   │ │
├───┘ │
│     │
└─────┘

こういう形の画像を用意しておいて(正方形の部分は100%透過・L字の部分は影になるので黒めの色で塗りつぶしておく),背景画像として設定すると,正方形の部分に読み込んだ画像が重なり,影付きのアイコンとして画面に表示される。

ソースは下記よりどうぞ。本題のLazyIconView.javaと,それを使ったサンプルのActivityを用意した。実際に動かすには,適当に背景用画像を作成してresフォルダに放り込む必要がある。

実行するとこんな感じになる。


*1:つまり,子孫ビューすべてのlayoutメソッドを呼ぶ

*2:LinearLayout,RelativeLayoutなどなど