詳解 RelativeLayoutの内部実装
by
HiroYUKI Seto
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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が参照できていない 例外を投げる