会社で作っているサービスのAndroidアプリにConstraintLayoutが未導入だったので多くの画面をConstraintLayoutで書き直しました。
アプリ自体が小規模から中規模で画面数は大小とリスト用の画面合わせて50レイアウト程度なのでそれほど大きくはないと思いますが、個人的には書き換えてよかったなと思っています。
ただいくつか実際に書き換えていく中で気がついた注意点などあったので簡単に書きたいと思います。
ConstraintLayoutは必ずしもパフォーマンスがよいわけではない(と思われる)
こちらの記事ではRelativeLayoutに比べて約40%早くなったと紹介がありました。
パフォーマンスを図ったわけではないので正確なことはいえないのですが以下の場合だと効果が高いのではないかと思います。
- RelativeLayoutを単純にConstraintLayoutに書き換えた
- LinearLayout等の入れ子構造をConstraintLayoutに書き換えて、かつ階層をなくした
また自分の書き方が悪かったからかもしれませんが以下の場合人間の目で体感できるくらい遅くなりました。
- ConstraintLayoutを複数の入れ子にした場合
- ConstraintLayoutを複数個(10個以上)並べた場合
ConstraintLayoutは入れ子構造がないフラットなレイアウトを心がける必要があると思いました。
個人的な印象ですがフラットにしている限りは人間の目で気になるようなパフォーマンスの悪化はありませんでした。
ただ計測していないため説得力もないので気になる方は必ず計測したほうがよいと思います。
ConstraintLayout chain制約
ConstraintLayoutではChain制約が非常に大きな役割を持っていると感じました。
設定できる制約は以下の3つです。
spread
均等揃えspread_inside
外側の要素を端によせて均等揃えpacked
余白なしの中央そろえ
書いていて思ったのですが言葉だと大変伝えにくいので以下のようになります。
特にspread
で均等割付が行えるのでよく使うと思います。
それ以外にもspread_inside
とpacked
がありそれぞれ最初は何に使うのかわからなかったのですが、spread_inside
を使って実現できた画面があるので簡単にご紹介します。
もしかしたら他にやり方があるかもしれないですし、そもそもそういうときに使うものではないというのはあるかもしれませんが一例として見ていただければと思います。
spread_inside
spread_inside
は外側の要素を制約の端によせて内側の要素は均等という制約です。
この端に寄せるというのが大事な場面がありました。
入力画面だったのですが、この画面は説明文と入力フィールドがあり画面下部にボタンがありました。
説明文の関係で長くなるのかもしれないのでScrollViewでラップしてあります。
こんな画面です。
見た目は大丈夫なのですが入力フィールド(TextInputLayout)をタップすると・・・。
こうなります。
入力フィールドにボタンが重なってしまいました。
ちなみにScrollViewでラップしない場合は重なりません。
これを防ぐために入力フィールドとボタンにChainして、更にChainStyleをspread_inside
にします。
するとこのように重なりません。入力フィールドとボタンが近いような気がしますが、その場合はマージンを設定すればよいと思われます。
ConstraintLayoutでmatch_parentは使えないわけではない
ConstraintLayoutでmatch_parent
は使えないと思っていたのですが使えます。
が、あんまりmatch_parent
を指定することがありませんでした。
代わりにレイアウトエディタでmatch_constraint
、XMLエディタでは0dp
を指定します。
この場合、その制約の中で最大になります。
テキストの場合は基本的に左右で制約をつけてlayout_widthを0dp
にすることが多かったです。
ellipsizeだけでは省略されない
こちらの記事がすごいわかりやすいです。
layout_widthをwrap_content
にしなければならない場合はlayout_constrainedWidth
制約を追加する必要があります。
左右(StartEnd)に制約ができる場合はwidthをmatch_constraint
にしてellipsize
を設定しても省略してくれます。
参考ソース(wrap_content)
参考ソース(wrap_content and layout_constrainedWidth)
参考ソース(match_constraint)
その他
基本的にはConstraintLayoutにしてよかったと思っているのですが、悩みも多少あります。
コード上からレイアウトを想像するのが難しい
LienarLayoutの場合積み重ねなのである程度レイアウトが想像できるのですが、ConstraintLayoutではまだ慣れていないこともあり難しいです。
必ずConstraintLayoutを使うべきなのか
LinearLayoutの使い分けが非常に難しいと感じています。
自分はConstraintLayoutの方が組みやすいのですが、LinearLayoutで組める場合もあり難しいなと思っています。
今のところはConstraintLayoutで組むつもりです。
まとめ
ConstraintLayoutにするとバイアスで位置を調整したり割合で配置したりRelativeLayoutやConstraintLayoutでは難しいことができます。
このConstraintLayoutという難しそうな名前のおかげで最初はとっつきにくい印象を持っていたのですが、実際使ってみると想像以上に柔軟に画面を作成できました。
やっぱり、実際やってみないとわからないなと感じました。