Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ConstraintLayoutの機能の実現

Ad449f3f4e595ade283a30c4f66010be?s=47 HiroYUKI Seto
February 03, 2018

 ConstraintLayoutの機能の実現

2018/2/9
DroidKaigi 2018 DAY02 room1 10:30~
発表の付録2

Ad449f3f4e595ade283a30c4f66010be?s=128

HiroYUKI Seto

February 03, 2018
Tweet

More Decks by HiroYUKI Seto

Other Decks in Technology

Transcript

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

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

  3. Guideline

  4. Guideline • 実態はView • constraint-layout側はほぼ空実装 ◦ 描画されないようにだけ実装されている ◦ ConstraintLayoutがmeasureをskipする •

    solver側はLinearSystemにSolverVariableを追加している ◦ Vertical or Horizontal or Percent で条件分け
  5. Group

  6. の前に

  7. ConstraintHelper

  8. ConstraintHelper • 実態はView • 参照されているViewのidの一覧を持つ • updatePreMeasure、updatePostMeasure • updatePreLayout、updatePostLayout •

    measureされない ◦ if文ですべてskipされている
  9. Group

  10. Group • View、ConstraintHelper • updatePreLayout ◦ 対象Viewのvisibilityとelevationを変更 • updatePostLayout ◦

    自身の幅と高さを0 ▪ VisibilityがGONEでないため レイアウトされる可能性がある その際に幅と高さを持たないため
  11. Barrier

  12. Barrier • View、ConstraintHelper • Typeを持つだけ ◦ 対象ViewのどこにBarrierを張るか

  13. Barrier • LinearSystemへの追加 ◦ 条件 ▪ LeftとTopの場合はGreaterThan ▪ RightとBottomの場合はLowerThan ◦

    strength ▪ match_constraintなWidgetがある場合LOW(1) ▪ match_constraintなWidgetがない場合BARRIER(7)
  14. Placeholder

  15. Placeholder • solver側に対応するクラスがない • updatePostMeasure ◦ contentのvisibilityをVISIBLE →自身のサイズに子Viewのサイズを代入 →contentのvisibilityをGONE ▪

    ConstraintWidgetはvisibilityがGONEだとsizeが0 • updatePreLayout ◦ contentにisInPlaceholderフラグを立てる ◦ 自身とcontentのvisibilityをVISIBLE
  16. Placeholderレイアウト • ConstraintLayout#onLayoutにif文 ◦ isInPlaceholderのViewはレイアウトをskip ◦ Placeholderのレイアウト時に 代わりにcontentのViewをレイアウト ◦ 恐らくレイアウトの順番を守るため

    ▪ 描画の上下関係が崩れないように
  17. Chain

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

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

  20. 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の場合は等分にする
  21. Chain.applyChainConstraints(5引数) 5. packed, spread, spreadInsideの処理 • packed or 要素Chainの1個 ◦

    先頭の項目を中央揃え(bias考慮)で配置 ◦ packedは1.の時に各要素が隣接するように配置 • spread ◦ Chainの要素を中央寄せで配置 • spreadInside ◦ Chainの端以外の要素を中央寄せで配置 ◦ Chainの端の要素をmarginの位置に配置