Android

既存アプリのレイアウトをConstraintLayoutに書き換えた

投稿日:2019/04/01 更新日:

会社で作っているサービスの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_insidepackedがありそれぞれ最初は何に使うのかわからなかったのですが、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という難しそうな名前のおかげで最初はとっつきにくい印象を持っていたのですが、実際使ってみると想像以上に柔軟に画面を作成できました。
やっぱり、実際やってみないとわからないなと感じました。

-Android

執筆者:


comment

メールアドレスが公開されることはありません。

関連記事

Firebaseにプロジェクトを追加する手順

Androidアプリを公開するときFirebaseを使っている方がほとんどだと思うのですが、自分で設定したことがありませんでした。 今回サンプルプロジェクトですが、Firebaseに設定してみました。 …

アサーションライブラリのGoogle Truthを使ってみる

AndroidXのTestではGoogleのアサーションライブラリのTruthが使われるみたいです。 Set up project for AndroidX Test Truthを必ず使えというよりも …

いつの間にかBottomNavigationにBadge機能がついていた・・・

先日、たまたまmaterial-components-androidのCatalogアプリを見ていたらBottomNavigationにBadge機能がついていました。 これ、最近追加されたんですかね …

Android Internal App Sharingのメモ

仕事でGoogle Play ConsoleのInternal App Sharingを使う機会があったのでメモを残します。 ##導入の経緯 アプリでAndroid app Bundleを導入する必要 …

IntelliJ IDEA(AndroidStudio)でもgit rebase squashできるよ!

普段開発しているとGitを使ってバージョン管理することが多いと思います。 その時によくローカルブランチを作って、変更をガンガンコミットしていきます。 ある程度実装してリモートブランチにマージする時に、 …