最終更新日:2020/09/23 原本2020/07/20

リッチなUIを作りやすくなったAndroid Studio 4.0の新機能を知ろう

 2020年5月28日に、Android Studio 4.0がリリースされました。2017年10月のバージョン3.0以来、およそ3年ぶりのメジャーアップデートとなります。デザインのための新機能を中心に、リッチなUIをより少ない労力で作り上げるための工夫がたくさん入ったバージョンとなりました。本記事では、バージョン4.0で追加された機能の概要を紹介します。

対象読者

  • Android Studio 4.0の新機能を把握したい方

前提環境

 筆者の検証環境は以下の通りです。

  • macOS Catalina 10.15.5
  • Android Studio 4.0
  • AndroidX ConstraintLayout 2.0.0-beta6

Android Studio 4.0の概要

 Android Studio 4.0では、特にデザインツールやビルドツールの面で多くの改善が行われました。公式ブログから、代表的な変更をいくつか抜粋します。

  • デザインに関する分野
    • 「MotionLayout」のアニメーションをGUIから作成・編集・プレビューできる「モーションエディタ」が新たに追加された
    • レイアウトインスペクタが改善され、リアルタイムかつ直感的に実機で描画されたレイアウトを確認できるようになった
    • さまざまな設定でレイアウトのプレビューを比較できる「レイアウトバリデーション」が追加された
  • 開発・分析の分野
    • CPUプロファイラのUIが改善され、CPUの稼働効率を確認しやすくなった
    • R8(旧ProGuard)のルールエディタにシンタックスハイライトなどの支援が追加された
  • ビルドの分野
    • 「ビルドアナライザ」でビルド全体のうちどのタスクに時間がかかっているのか見つけやすくなった
    • Java 8の標準ライブラリをminSdkVersionの制限なく利用できるようになった
    • フィーチャーモジュールに依存するダイナミックフィーチャーモジュールを作成できるようになった
    • build.gradleでビルド機能のオン/オフを切り替えるためのフラグが整理された
    • ビルドスクリプトとして「.kts」ファイルが正式サポートされた

 どの機能も、アプリ開発の中での細かい不便を解消する、よい改善になっています。それでは、具体的にどのような改善になっているのか、見ていきましょう。

モーションエディタについて

 まずは、Android Studio 4.0最大の目玉と言っても過言ではない、モーションエディタについて解説します。モーションエディタは、「MotionLayout」でビューをどのように動かすか(モーション)の設定を、Android Studio上のGUIで作成・編集するための機能です。従来はXMLで記述していた設定を、より直感的に設定できるようになりました。 

MotionLayoutのおさらい

 「MotionLayout」は、ビュー同士の関係性に制約をつけるためのレイアウトである、「ConstraintLayout」のサブクラスです。静的なレイアウトを定義するだけであれば、「ConstraintLayout」と同じ使い方ができますが、XMLで記述した「MotionScene」というデータを読み込ませることで、レイアウトにモーションを付与することができます。

 「MotionScene」には、次の3つのデータを定義します。

  • 開始時点でのレイアウト状態(constraintSetStart)
  • 終了時点のレイアウト状態(constraintSetEnd)
  • レイアウトを変化させる設定(transition)

 レイアウト状態は「ConstraintSet」という単位で定義されます。全体としては、図1のような関係になります。

図1:MotionLayoutに設定する項目
図1:MotionLayoutに設定する項目

 これを実行して丸をクリックすると、丸のビューが1秒かけて左上から右下にアニメーションする姿が見られます。これが「MotionLayout」です。

モーションエディタの始め方と概要

 それでは、新機能のモーションエディタをどのように使えばいいのか、確認していきましょう。まずは、通常の「ConstraintLayout」で作られたレイアウトをレイアウトエディタで開き、デザインエディタ上を右クリックします(図2)。

図2:レイアウトエディタでメニューを表示する
図2:レイアウトエディタでメニューを表示する

 「Convert to MotionLayout」という項目が現れるので、クリックします。すると、図3のように確認のUIが出てきます。

図3:MotionLayoutに変換してもよいかを確認するUI

図3:MotionLayoutに変換してもよいかを確認するUI

 ここで「Convert」を選択すると、レイアウトファイルが「MotionLayout」ベースに書き換えられ、付随する「MotionScene」のXMLファイルも作成されます。レイアウトファイルはリスト1のようになります。

[リスト1]res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/activity_main_scene"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>

 また、「MotionScene」のXMLファイルはリスト2のようになります。

[リスト2]res/xml/activity_main_scene.xml
<?xml version="1.0" encoding="utf-8"?>
<MotionScene 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <!-- レイアウトを変化させる設定 -->
    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
       <KeyFrameSet>
       </KeyFrameSet>
    </Transition>

    <!-- 開始時点でのレイアウト状態 -->
    <ConstraintSet android:id="@+id/start">
    </ConstraintSet>

    <!-- 終了時点のレイアウト状態 -->
    <ConstraintSet android:id="@+id/end">
    </ConstraintSet>
</MotionScene>

 リスト2の設定では、開始時点と終了時点で変更がないため、全体としては「何もしない」というモーションが設定されたことになります。

 「MotionLayout」を成立させるための一通りの設定ができましたので、「res/layout/activity_main.xml」をレイアウトエディタで見てみましょう(図4)。

図4:モーションエディタ
図4:モーションエディタ

 レイアウトエディタの右側に、モーションエディタが現れました。モーションエディタは図5のような構造をしています。

図5:モーションエディタの概要
図5:モーションエディタの概要

 「Transition」や、StartまたはEndの「ConstraintSet」をクリックして選択すると、下部のプレビューが切り替わります。また、Attributes(属性)も連動してプロパティを表示するので、モーションエディタを本格的に運用する場合は、レイアウトエディタのUI配置を図6のような形にするとよいでしょう。

図6:モーションエディタ利用時のおすすめの配置
図6:モーションエディタ利用時のおすすめの配置

 これで、モーションエディタを利用する準備が整いました。

モーションエディタでビューを動かす

 それでは、実際にビューを動かす設定をモーションエディタ上で行ってみましょう。今回は"Hello World"の 「TextView」を動かしてみます。

 まずは開始状態を設定するために、モーションエディタ上の「start」を選択します。プレビューを見ると、まだ開始状態の「ConstraintSet」にレイアウト上の「TextView」が紐づいていないことがわかります(図7)。

図7:TextViewがConstraintSetに紐づいていない
図7:TextViewがConstraintSetに紐づいていない

 この場合は、ビューを選択して、右上の編集ボタンをクリックすると「Create Constraint」のメニューが現れるので、これをクリックして実行します(図8)。

図8:Constraintを作成してビューを紐付ける
図8:Constraintを作成してビューを紐付ける

 すると、図7では空だった「Constraint」の欄にチェックが入ります(図9)。

図9:ConstraintSetにTextViewが紐づいた状態
図9:ConstraintSetにTextViewが紐づいた状態

 これで、「TextView」が 「MotionLayout」の操作対象になりました。終了状態のほうにも同様の操作を行います。

 ようやく開始状態のレイアウトを操作できるようになりました。モーションエディタで開始状態を選択したまま、左側のデザインエディタで「TextView」を左上に動かします(図10)。

図10:開始状態を作る
図10:開始状態を作る

 通常のレイアウトエディタで「ConstraintLayout」を扱うときと同様に、Attributesに設定内容がリアルタイムに反映され、細かく設定できます。

 終了状態にも同様の操作を行い、「TextView」を右下に動かしましょう。

図11:終了状態を作る
図11:終了状態を作る

 これで、最も単純な「MotionScene」が作成できました。動作を確認するには、モーションエディタの矢印をクリックして、「Transition」のプレビューを開きます(図12)。

図12:Transitionのプレビュー
図12:Transitionのプレビュー

 デザインエディタに移動の経路が表示されました。再生ボタンをクリックすると、実際に動く様子が見られます(図13)。

図13:Transitionを再生する
図13:Transitionを再生する

 このようにGUI上で動作を確認できると、トライアンドエラーが捗りそうです。

レイアウトインスペクタの刷新

 レイアウトインスペクタにも大きな更新がありました。以前から、デバッグモードで動作中のアプリのレイアウト階層を閲覧する方法はありましたが、あまり直感的ではありませんでした。今回刷新されたレイアウトインスペクタでは、より直感的にレイアウトのデバッグができるようになっています。

 レイアウトインスペクタは右下のツールウィンドウから開きます(図14)。

図14:レイアウトインスペクタの入り口
図14:レイアウトインスペクタの入り口

 レイアウトインスペクタを開いて、アプリのデバッグを開始すると、図15のような見た目になります。

図15:新しいレイアウトインスペクタ
図15:新しいレイアウトインスペクタ

 左ペインにコンポーネントツリー、中央ペインにプレビュー、右ペインに属性というレイアウトになり、レイアウトエディタと似た見た目になったことがわかります。レイアウトインスペクタで見つけた問題を、レイアウトエディタで解決するときにどこを見ればよいのか、とてもわかりやすくなりました。

ライブレイアウトインスペクタ&ローテーション

 レイアウトインスペクタの新機能はこれだけではありません。API Level 29(Android 10)以降で使える機能として、リアルタイムにレイアウト情報が反映される「ライブレイアウトインスペクタ」と、3Dでレイアウト階層を確認できる「ローテーション」が追加されました。

 ライブレイアウトインスペクタは、図16のチェックボックスをオンにすることで有効になります。

図16:ライブレイアウトインスペクタを有効にする
図16:ライブレイアウトインスペクタを有効にする

 また、ローテーション機能は、右下の四角いアイコンをクリックすることで有効になります(図17)。

図17:ローテーション機能を有効にする
図17:ローテーション機能を有効にする

 ローテーション機能を使うことで、複雑なUIでも階層を直感的に把握できるようになります(図18)。

図18:ローテーション機能
図18:ローテーション機能

 リアルタイムかつ直感的にレイアウトの状態を確認できるようになるため、現場で重宝する機能になりそうです。

レイアウトバリデーション

 これまでも、レイアウトのプレビュー時に、デバイスサイズや言語設定、ダークモードの有無などを切り替えることはできましたが、複数の設定を一度に表示して、見比べることはできませんでした。今回追加された「レイアウトバリデーション」では、複数の設定を別々に表示し、レイアウトがどのように変化するのかを見比べられるようになりました。

 レイアウトバリデーションは、レイアウトエディタを開いているときに右側のツールウィンドウから開きます(図19)。

図19:レイアウトバリデーション
図19:レイアウトバリデーション

 比較分野はいくつか選択できますが、初期表示ではGoogle公式Android端末である歴代Pixelシリーズの画面サイズを比較できる、「Pixel Devices」という項目になっています。画面サイズごとにレイアウトにどのような差が出るのかを比較するためのものです。

 他の比較分野として、さまざまな色盲のパターンで画面の見やすさを比較する「Color Blind」と、システム側のフォントサイズ設定によるレイアウト崩れを確認するための「Font Sizes」がプリセットで用意されています。

開発関連の改善と新機能

 開発に関連する新機能としては、「CPUプロファイラ」の改善と、R8のルールエディタの改善があります。

 CPUプロファイラは、デバッグ中にどのスレッドがどの程度CPUを使っていたかを計測するための機能です。画面下部の「Profiler」のツールウィンドウから使うことができます(図20)。

図20:CPUプロファイラ
図20:CPUプロファイラ

 効率よくCPUを使用したい場合に確認するとよいでしょう。

 もう一つの大きなトピックがあります。R8(旧ProGuard)のルールを記述するためのエディタが整備され、シンタックスハイライトや補完が効くようになりました(図21)。

図21:R8の設定ファイル
図21:R8の設定ファイル

 従来は、文法やパッケージ名の間違いに気づかないままリリースビルドが失敗した場合、その原因を究明するために多くの時間を費やしていました。しかしこの機能によって、より正しい設定ファイルを記述できるようになりそうです。

ビルド関連の改善と新機能

 ビルドに関する分野では、「ビルドアナライザ」という新機能が追加されました。ビルドの完了時に、リンクが表示されるので、ここから開きましょう(図22)。

図22:ビルドアナライザの入り口
図22:ビルドアナライザの入り口

 ビルドアナライザは、ビルドのどのタスクにどの程度の時間がかかっているのかを確認するための機能です(図23)。

図23:ビルドアナライザ
図23:ビルドアナライザ

 各タスクの実行にかかった秒数が表示されるので、想定外に時間がかかっているタスクが見つけやすくなり、対策が取れるようになります。

Android Gradle Pluginの改善

 Android Studioに合わせて、Android Gradle Pluginもバージョン4.0.0になりました。大きな変更もありますので、確認しておきましょう。

Java 8の標準ライブラリをサポート

 これまでも、ラムダ式やメソッド参照と言ったJava 8の文法は、minSdkVersionに関係なく使えていましたが、「java.util.stream」などの標準ライブラリはminSdkVersion 24以降でしか利用できませんでした。今回の更新で、専用のライブラリを通じて、Java 8以降の標準ライブラリのAPIが利用できるようになりました。これに関しては、公式ドキュメントの該当ページで言及されています。

 この環境を有効にするには、build.gradleにリスト3の記述を追加します。

[リスト3]Java 8の標準ライブラリAPIを有効にするための設定
android {
  defaultConfig {
    // minSdkVersionが20以下の場合に必要
    multiDexEnabled true
  }

  compileOptions {
    // 新しい標準APIのサポートを有効にするためのフラグ
    coreLibraryDesugaringEnabled true
    // Java 8言語を使えるようにするための設定
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  // Android向けの標準ライブラリ
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
}

 これらの設定をすることにより、Javaコード上で次のAPIが利用できるようになります。

  • Stream API(「java.util.stream」)
  • 「java.time」のサブセット
  • 「java.util.function」
  • 「java.util.{Map,Collection,Comparator}」に最近追加されたメソッド
  • Optional(「java.util.Optional」、「java.util.OptionalInt」、「java.util.OptionalDouble」)と、関連する便利なクラス群
  • 「java.util.concurrent.atomic」への機能追加(「AtomicInteger」、「AtomicLong」、「AtomicReference」へのメソッド追加)
  • 「ConcurrentHashMap」

 従来、Stream APIの代替ライブラリであるLightweight-Stream-APIや、「java.time」の代替ライブラリであるThreeTenABPを利用していた開発者にとっては、待望の正式なAPIとなります。

ビルド機能のフラグのAPIが変更された

 ViewBindingやDataBindingを利用する際には、build.gradleでフラグを有効にする必要があります。従来は 「android」ブロックの直下に「viewBinding.enabled」や「dataBinding.enabled」というフラグを設定していましたが、今回のリリースでフラグの階層が整理されました(リスト4)。

[リスト4]新しいフラグ設定
android {
  // これらのフラグ指定方法は非推奨になった
  // viewBinding {
  //   enabled = true
  // }
  // dataBinding {
  //   enabled = true
  // }

  // 新しい指定方法
  buildFeatures {
    // ViewBinding機能を有効にするかどうか
    viewBinding = false
    // DataBinding機能を有効にするかどうか
    dataBinding = false
    ...
  }
}

 従来の方法は非推奨になったので、注意しましょう。

Kotlin DSLがビルトインサポートになった

 build.gradleはGroovy言語のDSL(ドメイン固有言語)として書かれていましたが、Gradle 5.0からはKotlinでもGradleのスクリプトが書けるようになりました。以前からAndroid向けのサポートも試験的に導入されていましたが、今回から正式サポートとなりました。Kotlin DSLを利用する場合は、「build.gradle.kts」にGradleスクリプトを記述することになります。

 従来のGroovyでのスクリプトも非推奨になったわけではありませんし、Kotlin DSL版も2021年いっぱいまでを目処に使い勝手の改善・整理を行っていくらしいので、急いで導入する必要はありません。

まとめ

 Android Studio 4.0の新機能を紹介しました。モーションエディタや新しいレイアウトインスペクタの追加によって、デザイナー職の方々がUIを微調整しやすくなることが期待できます。また、Javaの標準APIがサポートされたことは、Java言語でアプリを書き続けるプログラマーたちにとって、大きな力となるでしょう。

 4.0はメジャーバージョンアップの名に恥じない、強力なアップデートになりました。皆さんの現場でも、是非導入してみてください。