詳解 RelativeLayoutの内部実装
by
HiroYUKI Seto
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
DroidKaigi 2018付録1 詳解 RelativeLayoutの 内部実装 株式会社ノハナ 瀬戸優之 @seto_hi
Slide 2
Slide 2 text
RelativeLayoutのポイント =Graph
Slide 3
Slide 3 text
Graph グラフ(英: Graph)とは、 ノード(頂点)群とノード間の連結関係を表す エッジ(枝)群で構成される抽象データ型、 and・orその実装である具象データ型である。 (wikipedia)
Slide 4
Slide 4 text
DependencyGraph ● 有向グラフ ● mNodes = 子Viewすべて、ArrayList ● mKeyNodes = IDを持つ子View、SparseArray Node ● dependents = 参照しているNode ● dependencies = 参照されているNode
Slide 5
Slide 5 text
RelativeLayout#onMeasure
Slide 6
Slide 6 text
RelativeLayout#onMeasure 1. DependencyGraphを作る 2. 横方向でGraphのrootからmeasure、仮レイアウト 3. 縦方向でGraphのrootからmeasure、仮レイアウト ○ 自身のサイズも仮決定
Slide 7
Slide 7 text
RelativeLayout#onMeasure 4. 自身がwrap_contentなら ○ 子のサイズとMeasureSpecから自身のサイズを修正 ○ 中央寄せのViewの位置を修正 5. Gravityによって位置を本決め 6. setMeasuredDimensions
Slide 8
Slide 8 text
mesureでの仮レイアウト ● 参照のGraphのrootからmeasure + 仮レイアウトしていく ● measure対象のViewが参照しているViewは 必ず仮レイアウト済み ● measureさえすればmeasure対象のViewの 仮レイアウト位置が確定できる
Slide 9
Slide 9 text
子ViewのmeasureSpec 1. 左右(or上下)ともに参照しているViewがある ○ 左右(or上下)のViewの間のサイズ + EXACTLY 2. 1.でない場合 ○ 子Viewがサイズ決め打ち ■ 子Viewのサイズと余りサイズの最小値 + EXACTLY ○ 子Viewがmatch_parent ■ RelativeLayoutの余りサイズ + EXACTLY※ ○ 子Viewがwrap_content ■ RelativeLayoutの余りサイズ + AT_MOST※ ※余りがなければ0 + UNSPECIFIED
Slide 10
Slide 10 text
RelativeLayout#onLayout
Slide 11
Slide 11 text
RelativeLayout#onLayout ● measure通りにレイアウトするだけ ○ RelativeLayout.LayoutParamsが位置と座標を持つ ■ mLeft, mTop, mRight, mBottom ● シンプル!
Slide 12
Slide 12 text
循環参照の検知
Slide 13
Slide 13 text
循環参照の検知 ● RelativeLayoutで循環参照は禁止 ○ rightOfのleftOfが自身のような場合 ○ ConstraintLayoutは一部OK(Chainになる) ● グラフの参照で解決
Slide 14
Slide 14 text
DependencyGraph ● mNodes = 子Viewすべて、ArrayList ● mKeyNodes = IDを持つ子View、SparseArray Node ● dependents = 参照しているNode ● dependencies = 参照されているNode
Slide 15
Slide 15 text
DependencyGraph#getSortedViews 1. GraphのrootをDequeに入れる 2. Dequeからグラフの頂点のNodeをpoll 3. 2.を参照している子Nodeに対して 3.1. 参照されているNodeがないならばDequeに追加 3.2. 参照されているNodeがあれば何もしない 4. Dequeが空ならば5、 Dequeが空でないならば2.に戻る 5. すべてのEdgeをDequeに追加できていない場合は 例外を投げる
Slide 16
Slide 16 text
循環参照の検知(正常系) A B C Dequeue
Slide 17
Slide 17 text
循環参照の検知(正常系) A B C Dequeue A 1.RootをDequeueに追加
Slide 18
Slide 18 text
循環参照の検知(正常系) A B C Dequeue B 2.pollして消去 3.1.Dequeueに追加
Slide 19
Slide 19 text
循環参照の検知(正常系) B C Dequeue C 3.1.Dequeueに追加 2.pollして消去
Slide 20
Slide 20 text
循環参照の検知(正常系) C Dequeue 2.pollして消去
Slide 21
Slide 21 text
循環参照の検知(正常系) Dequeue 5.Dequeueが空で すべてのEdgeを参照したので終了
Slide 22
Slide 22 text
循環参照の検知(異常系) A B C Dequeue 循環参照
Slide 23
Slide 23 text
循環参照の検知(異常系) A B C Dequeue A 1.RootをDequeueに追加
Slide 24
Slide 24 text
循環参照の検知(異常系) A B C Dequeue 2.pollして消去 3.2.参照があるので Dequeueに追加しない
Slide 25
Slide 25 text
循環参照の検知(異常系) B C Dequeue 5.Dequeueが空なのにすべてのEdgeが参照できていない 例外を投げる