カスタム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フォルダに放り込む必要がある。
実行するとこんな感じになる。