15
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ConstraintLayoutのクラス解説

Posted at

Google I/O 2018でConstraintLayout2.0が発表されると思いますが、その前に1.1.0の内部実装を読んでおきましょう。

はじめに

DroidKaigi 2018でConstraintLayoutの内部実装に関する発表をした者です。動画はこちら
発表の中ではレイアウトアルゴリズムを簡単に紹介することしかできなかったので、もう少し踏み込んだ内容の紹介をしたいと思います。
この記事では各クラスの役割について記述します。

環境

ConstraintLayout Ver1.1.0
ConstraintLayoutはbetaのバージョンが1つ上がるだけで内部実装がかなり変わるので、違うバージョンでは参考にならない可能性が高いです。
Ver1.1.0のコードは公開されていないので、逆コンパイルしたコードを読んでいます。
なお、beta-5までならこちらに公開されています。

DroidKaigiの内容のおさらい

ConstraintLayoutの構成

constraint-layoutライブラリはconstraint-layout-solverライブラリに依存しています。
constraint-layoutライブラリには最低限の実装しかなく、レイアウトの複雑な計算のほとんどはconstraint-layout-solver側で行われています。
またconstraint-layout-solverはAndroidに依存しておらず、(使おうと思えば)Android以外のプロジェクトにも使い回せるようになっています。

ConstraintLayoutのレイアウトアルゴリズム

ConstraintLayoutはView同士の関係を一次方程式や一次不等式に見立て、線形計画問題の最適解を求めることでレイアウト位置を決定しています。
線形計画問題の最適解を求めるためにCassowaryという計算アルゴリズムを使っています。
このあたりの詳細は @inamiy さんのこちらの記事が参考になります。
(iOSのAutoLayoutもConstraintLayoutと同じくCassowaryを使ってレイアウトを解決してます)

constraint-layout-solverの各クラスの役割

一部重要そうでないクラスは省略します。

android.support.constraint.solver パッケージ

ArrayLinkedVariables

ArrayベースのLinked List。高速でメモリ効率が良いらしいです。
ArrayBackedVariablesLinkedVariablesからインスピレーションを受けているそうです。

ArrayVariables

使っている部分を見つけられず。
ArrayLinkedVariablesからheadlastが取り除かれた実装になっています。

ArrayRow

線形計画問題の行列の「行」を表現するクラス。
LinearSystem.Rowを継承しています。

LinearSystem

線形方程式の最適解を求めるクラス。solverパッケージでも重要なクラスです。
Cassowaryがここに実装されています。

Metrics

LinearSystemの状態を保持する値クラス。

SolverVariable

ViewやContainWidgetのレイアウトをLinearSystemで解決するために変換した値を保持するクラス。
最適解の値も保持をします。

android.support.constraint.solver.widget パッケージ

ConstraintWidget

Androidフレームワークで言うViewクラス。

WidgetContainer

Androidフレームワークで言うViewGroupクラス。ConstraintWidgetを継承しています。

ConstraintWidgetContainer

Androidフレームワークで言うConstraintLayoutクラス。WidgetContainerを継承しています。

ConstraintHorizontalLayout, ConstraintTableLayout

constraint-layoutで使われていない秘密のクラス。
ごにょごにょするとこんな感じの成果物が得られます。
ConstraintLayout2.0に期待ですね。

Helper

constraint-layoutで言うConstraintHelperクラス。

Barrier

Barrierクラス。Helperを継承しています。

Guideline

Guidelineクラス。ConstraintWidgetを継承しています。
(他のConstraintWidgetを参照しないため、HelperではなくConstrantWidgetを継承している)

Chain

1.1.0-beta2から追加されたクラス。
Chainクラスを実現するクラス。staticメソッドが2つあるだけ。
各ConstraintWidgetの関係からいい感じにArrayRowを作成してChainを実現しています。

ConstraintAnchor

ConstraintWidget同士の関係を表すクラス。
layout_constraintTop_toTopOfなどで定義した「ConstraintWidgetの各辺がどのConstraintWidgetのどの辺の位置に参考にレイアウトするか」の情報を表します。

Optimizer

レイアウトの最適化を行うクラス。
各ConstraintWidget同士の関係を、LinearSystemで簡単に解けるように最適化します。
DroidKaigi(1.1.0-beta5参考)では「簡単なレイアウトを線形計画問題を解かずに計算するクラス」という説明をしましたが、1.1.0では動作が変わっています。ご注意ください。

Optimizer#checkMatchParent

ConstraintLayoutの子ViewのLayoutParamsがmatch_parentの場合、親と同じ幅or高さになるように設定して最適化します。

Optimizer#analyze

ConstraintWidgetの幅や高さが数値で設定されている場合や、match_constraintになっている場合に最適化を行います。

Optimizer#applyChainOptimized

メソッド名の通り、ChainになっているConstraintWidgetの関係を最適化します。

ResolutionNode

1.1.0-beta6から追加されたクラス。
ConstraintAnchorは各辺の接続情報の値クラスでしたが、このクラスはinvalidateresolveといったメソッドを持ちます。

ResolutionAnchor

1.1.0から追加されたクラス。ResolutionNodeを継承しています。
各辺の接続情報をLinearSystemへ追加したりもします。

ResolutionDimension

1.1.0から追加されたクラス。ResolutionNodeを継承しています。
OptimizationLeveldimenstionsの時に使われます。
float型のvalueを持ちます。

15
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?