Slide 1

Slide 1 text

DroidKaigi 2018付録2 ConstraintLayout の 機能の実現 株式会社ノハナ 瀬戸優之 @seto_hi

Slide 2

Slide 2 text

略解 ConstraintLayoutの 機能の内部実装 https://qiita.com/hiroyuki-seto/items/7b8781b336efba14872e のもう少し深い話

Slide 3

Slide 3 text

Guideline

Slide 4

Slide 4 text

Guideline ● 実態はView ● constraint-layout側はほぼ空実装 ○ 描画されないようにだけ実装されている ○ ConstraintLayoutがmeasureをskipする ● solver側はLinearSystemにSolverVariableを追加している ○ Vertical or Horizontal or Percent で条件分け

Slide 5

Slide 5 text

Group

Slide 6

Slide 6 text

の前に

Slide 7

Slide 7 text

ConstraintHelper

Slide 8

Slide 8 text

ConstraintHelper ● 実態はView ● 参照されているViewのidの一覧を持つ ● updatePreMeasure、updatePostMeasure ● updatePreLayout、updatePostLayout ● measureされない ○ if文ですべてskipされている

Slide 9

Slide 9 text

Group

Slide 10

Slide 10 text

Group ● View、ConstraintHelper ● updatePreLayout ○ 対象Viewのvisibilityとelevationを変更 ● updatePostLayout ○ 自身の幅と高さを0 ■ VisibilityがGONEでないため レイアウトされる可能性がある その際に幅と高さを持たないため

Slide 11

Slide 11 text

Barrier

Slide 12

Slide 12 text

Barrier ● View、ConstraintHelper ● Typeを持つだけ ○ 対象ViewのどこにBarrierを張るか

Slide 13

Slide 13 text

Barrier ● LinearSystemへの追加 ○ 条件 ■ LeftとTopの場合はGreaterThan ■ RightとBottomの場合はLowerThan ○ strength ■ match_constraintなWidgetがある場合LOW(1) ■ match_constraintなWidgetがない場合BARRIER(7)

Slide 14

Slide 14 text

Placeholder

Slide 15

Slide 15 text

Placeholder ● solver側に対応するクラスがない ● updatePostMeasure ○ contentのvisibilityをVISIBLE →自身のサイズに子Viewのサイズを代入 →contentのvisibilityをGONE ■ ConstraintWidgetはvisibilityがGONEだとsizeが0 ● updatePreLayout ○ contentにisInPlaceholderフラグを立てる ○ 自身とcontentのvisibilityをVISIBLE

Slide 16

Slide 16 text

Placeholderレイアウト ● ConstraintLayout#onLayoutにif文 ○ isInPlaceholderのViewはレイアウトをskip ○ Placeholderのレイアウト時に 代わりにcontentのViewをレイアウト ○ 恐らくレイアウトの順番を守るため ■ 描画の上下関係が崩れないように

Slide 17

Slide 17 text

Chain

Slide 18

Slide 18 text

Chain ● staticメソッドが2つ ○ beta3からクラス化、beta2まではOptimizer内にあった ● 300行くらいあって複雑!

Slide 19

Slide 19 text

Chain ● ConstraintWidgetContainer#addChildrenToSolverで LinearSystemに数値を追加する最後に Chain.applyChainConstraints(3引数)を呼ぶ ● Chain.applyChainConstraints(3引数)では chainそれぞれにChain.applyChainConstraints(5引数)を呼 ぶ

Slide 20

Slide 20 text

Chain.applyChainConstraints(5引数) 1. chainの要素でwhile文 ○ LinearSystemに追加 2. chainの端の制約をLinearSystemに追加 3. ConstraintLayoutがwrap_content ○ chainの端が親をはみ出さない制約を LinearSystemに追加 4. match_constraintなwidget ○ MATCH_CONSTRAINT_SPREADか MATCH_CONSTRAINT_RAITOの場合は等分にする

Slide 21

Slide 21 text

Chain.applyChainConstraints(5引数) 5. packed, spread, spreadInsideの処理 ● packed or 要素Chainの1個 ○ 先頭の項目を中央揃え(bias考慮)で配置 ○ packedは1.の時に各要素が隣接するように配置 ● spread ○ Chainの要素を中央寄せで配置 ● spreadInside ○ Chainの端以外の要素を中央寄せで配置 ○ Chainの端の要素をmarginの位置に配置