注意!
この記事はQiitaにて公開されていた内容をimportしたものです。
これらの内容は場合によっては陳腐化していて役に立たなくなっていたり、有害であったり、現在の著者の主張と異なることがあります。
皆様の判断の上でご利用いただけますと幸いです(度を超してヤバいものは著者に連絡して頂ければ対応します m(_ _)m)
はじめに
Android Support Library rev.26 より Percent Support Library がdeprecatedになるため、ConstraintLayoutへの移行を行う必要があります(ただしrev.26は現在のところalpha版のため、deprecated自体が取りやめになる可能性はあるかもしれません)。
- Recent Support Library Revisions | Android Developers (ページ下部の言語設定で「English」に設定してご覧ください)
一方でPercent Support LibraryからConstraint Layoutへの変換は、グラフィカルエディタ(layout xmlを開いた画面のDesign
タブ)のComponent Tree
を右クリックして表示されるConvert *** to ConstraintLayout
ではうまく変換できない(できたらラッキーだけどたぶん難しい)為、適切にViewの振る舞いを理解して書き直してあげる必要があります。
あと上記記事で具体的な移行方法が示されていないのもあるのですが、まぁそれはそれで。
というわけで、Percent Support LibraryをConstraintLayoutにマイグレーションする手順(の覚え書き)です。
なお、本資料で紹介するAPIは constraint-layout ver.1.0.2 準拠です。
ここで説明しないこと
ConstraintLayoutの解説そのものは省いています。あくまでPercent Support Libraryからの移行に関するポイントのみに絞っています。けれども完璧を目指したり、やや複雑なことをしているなら、ConstraintLayoutの全容を把握する必要はありそうです。
ConstraintLayoutのことをもっと知りたい方は、まずはConstraintLayoutのクラス・リファレンスを確認してください。だいたい全てそこに書かれています。日本語記事をお望みなら、Qiita内を検索してみるか、僕が最近購入した書籍ではTechBoosterさんの「Colorful Android」第2章が参考になりました。
マイグレーション・ガイド
0. app
のbuild.gradle
の書き換え
build.gradleに記述する前に、SDK ManagerよりConstraint Layout関連ファイルを取得しておくこと。 (ちなみにSupport LibraryのバージョンとConstraintLayoutのバージョンは同じものではないので、定数定義してる場合は気をつけて)
compile "com.android.support:percent:${SUPPORT_PACKAGE_VERSION}"
↓
compile "com.android.support.constraint:constraint-layout:${CONSTRAINT_LAYOUT_VERSION}"
1. 見た目が一致するように書き換える
とはいえ不慣れな状態からいきなりガッと書き換えるのは難しいので、どこかにダミーのlayout xmlを置き、そこでConstraintLayoutを試しながら作業すると理解がよいかと思います。
重要: ConstraintLayoutにおける layout_width, layout_height について
ConstraintLayout内ではmatch_parent
は使えないので移行時には書き換える必要があります。
例えば layout_width="match_parent"
相当のものは以下のように記述できます:
android:layout_width="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
ちなみに 0dp
はConstraintLayoutでは MATCH_CONSTRAINT
であると記されています。
詳しくはConstraintLayoutクラス・リファレンスの「Widgets dimension constraints」をご覧下さい。
A. アスペクト比
Percent Support Library導入で一番多い使い方ではないでしょうか。 動画プレイヤーやサムネイルなどで16:9比率でViewサイズを設定したい場合など。
Percent Support Libraryの子要素で以下のような定義をしていたとする:
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_aspectRatio="178%"
これをConstraintLayoutの子要素で定義し直すと以下:
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
"16:9"
と記述した箇所の先頭に、"H,16:9"
とか "W,16:9"
と記述することもできます。
H,Wのいづれも記述しない場合、親View(ConstraintLayoutそのもの)からはみ出さず、それでいてアスペクト比を維持した幅高さにしてくれます。
Hを先頭につけると、 高さ(height)を設定比率に添う形にし、幅(width)を要素がとることができる最大幅まで広げます。
Wを先頭につけると、幅(width)を設定比率に添う形にし、高さ(height)を要素がとることができる最大幅まで広げます。
B. パーセント指定の幅高さ
これもPercent Support Libraryの使われ方として多いのではないでしょうか。 例えば横画面時に6:4の比率でViewを配置したい場合など。
おいそこの古参、「LinearLayout+weight指定でおk」とかうるさいぞ
Percent Support Libraryにて以下のような定義をしていたとする:
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_red_light"
android:gravity="center"
android:text="Hello World!"
app:layout_widthPercent="60%"
/>
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_blue_light"
android:gravity="center"
android:text="Sayonara World!"
android:layout_toRightOf="@id/textView"
app:layout_widthPercent="40%"
/>
</android.support.percent.PercentRelativeLayout>
これをConstraintLayoutの子要素で定義し直すと以下:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_red_light"
android:gravity="center"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/guideline"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_blue_light"
android:gravity="center"
android:text="Sayonara World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/guideline"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.6"/>
</android.support.constraint.ConstraintLayout>
キーポイントは Guideline
で、これ自体はViewとして何らかの表示をするものではありません。ConstraintLayoutにおいて文字通りガイドライン線をつくり、ガイドライン線に沿ってViewを配置できるようになります。
グラフィカルエディタからはConstraintLayout上で右クリックし、メニュー内の該当項目を選ぶことでGuidelineを作成できます。
orientationでvertical(縦線)、horizontal(横線)指定をします。
layout_constraintGuideはViewのstartもしくはendからの長さでも指定できます(それぞれプロパティあり)。
個人的な意見として、これまでのweight指定や子要素へのpercent指定よりかは、Guidelineで制約を制御できるのは画期的で、仕様変更時(例えば6:4を7:3にしてほしいとか)のヒューマンエラーも減らせるし良さそうに見えますが、欠点は慣れ親しんだテクニックの方が何も見ないでも書けるから、わざわざConstraintLayout使うまでもないって事だな!
ところで、6:4とかではなく等間隔に3つ以上のViewを配置したい場合は、Chainを検討してください。そっちのほうがGuidelineでやるよりシンプルです。
詳しくはConstraintLayoutのクラス・リファレンスの「Chains」の項目を参照。
(でもそれならネスト深くなってもLinearLayout+weightのほうが楽よなぁ)
まとめ
ConstraintLayoutを使うかどうかはともかく、PercentSupportLibraryの移行がんばりましょう。
ただなんでか知らないけど個人的なConstraintLayoutへの信用が高くないのでなぁ