Viewについて

今回は、本当に自分の為の覚え書きというもの・Androidの基本的なところです。Viewに関してです。ここの翻訳・抜粋のような感じになります。

ViewのPosition

ViewはTree構造になってます。一番上にRootとなるViewが存在し、そのViewの中に子Viewがあり、その子Viewにもまた子Viewが存在するというような感じです。ViewのPositionはView#getLeft()やView#getTop()などのmethodeでX軸方向、Y軸方向の位置を取得することが出来ますが、それは直接の親のViewからの相対位置になります。

ViewのSize

ViewのSizeには2種類あります。

  1. measured width/height
  2. width/height

measured width/heightは、Viewが親のViewの中でどれ位、大きくなりたいのかということを表すSizeです。
measured width/heightはView#getMeasuredWidth()、View#getMeasuredHeight()で取得できるものです。

width/heightはViewの実際のSizeになります。measured width/heightとは必ずしも一致しません。
width/heightはView#getWidth()、View#getHeight()で取得できるものです。

Layout

ViewのLayoutには2回のProcessがあります。View#measure()で行われる個々のViewのsizeを計るprocessと、View#layout()で行われる個々のViewのlayoutを行うprocessです。どちらのProcessも親のViewから子のViewへとprocessが進んで行きます。
まず、始めにViewの大きさを決定し、その後、その値をもとに画面上にViewを配置していくというイメージですね。

View#measure()が終了する時点で、View#getMeasuredWidth()とView#getMeasuredHeight()で返される値がsetされている必要があります。なので、measured width/heightはView#measure()が終了して始めて、意味のある値がsetされるということですね。constructor内でsizeを取得するのは意味がないということです。

measuring processでは下記の2つのclassが使用されて、sizeが決められます。

  1. View.MeasureSpec
  2. LayoutParams(ViewのSubclassによりsubclass化されたLayoutParamsも存在します)


View.MeasureSpecは親のViewから子Viewに課せられる制約です
。(親のViewが子Viewにどういったsizeになって欲しいかというもの)

LayoutParamsは逆で、子Viewがどの位のsizeになりたいかというものです。(親のViewめいいっぱいの大きさになりたいとか、Backgroundに設定されるIconのsizeを表示できる位のおおきさになりたいとか)

Eventが発生し、Viewのsizeやlayoutを変更しなくてはならなくなった場合はView#requestLayout()を呼ぶ事により、上記のprocessが開始されます。

No Process OverrideするCallback method Description
1 measure() onMeasure() View.MeasureSpecやLayoutParamsを使用しViewのsizeを決定
2 layout() onLayout() 1のProcessをもとにViewの位置(実size)を決定

Drawing

上記のLayout processでViewのsizeや位置がきまりましたので、このProcessでViewのcontentを描画していきます。同じように親のViewから子Viewに向かって描画のProcessが進んで行きます。Viewのbackground imageを設定している場合はView#onDraw()が呼ばれる前に描画されます。あるViewの再描画を行う場合はView.invalidate()を呼びます。ただし、invalidではない領域(親のView)に属するViewは描画されません。

Tags

これは個人的な興味ですが(全部そうか...)、Viewにはtagというものがあって、それにより特定のViewとdataなりobjectを紐づける事が出来ます。List viewなど使用されます。


それでは最後にViewのCallback methodの呼ばれる順番を表にして終わりたいと思います。

No Callback method Description
1 Constructors codeから呼ばれるconstructorもあればXMLからinflateされて呼ばれるconstructorもあります。後者の場合はAttributeSetをsuper()に渡す必要有り
2 onFinishInflate() Viewとその子ViewがXMLからinflateされた後に呼ばれる
3 onMeasure() Viewのsizeを計る際に呼ばれる。measured width/heightを決定する。View.MeasureSpec、LayoutParamsが使用される
4 onLayout() 実sizeを決定し、子Viewを配置する
5 onDraw() IconやTextといったContentを描画する

HashTag #Android