公式トレーニング「Android Kotlinの基礎」について

`Android Jetpack`の入門として[公式サイト](https://developer.android.com/jetpack?hl=ja)で紹介されているチュートリアル「[Android Kotlin の基礎](https://developer.android.com/courses/kotlin-android-fundamentals/overview?hl=ja)」を紹介します。

この記事は何かしらAndroidアプリ開発の入門書を読み終えたくらいの方向けに書いています。
このチュートリアルから学習をスタートすることはお勧めしませんが、Androidの実践的な開発で用いられる要素技術が広く紹介されているので学習の次のステップとしては非常にお勧めできる内容です。

ただ内容は結構ボリューミーで、**10個のレッスン、計33個ものコードラボで構成されています**。
英語読み込みながら全部マジメに取り組むと相当時間かかりま。

内容はすべてサンプルアプリを作りながらのハンズオン形式ですので手を動かしながら学びたい方には合っているかと思います。
この記事では各章で作成するサンプルアプリと学ぶ内容を紹介していますので、興味があるトピックがあればコードラボを覗いてみると良いかと思います。

そして始める前に言っておきます。
**この記事めっちゃ長いです**。

***

# レッスン1: 初めてのアプリの作成

> レッスン 1 では、Kotlin を使用するように Android Studio を設定する方法と、アプリを作成する方法について説明します。最初に「Hello World」を作成し、続いて、画像ファイルとクリック ハンドラを使用するアプリを作成します。Android プロジェクトの作成方法、Kotlin Android アプリでのビューの使用方法や変更方法、アプリの後方互換性を確認する方法について学習します。また、API レベルと Android Jetpack ライブラリについても学習します。

内容は基礎的で、入門書読んでれば既知の内容がほとんどです。


## 1.1 [Install Android Studio](https://developer.android.com/codelabs/kotlin-android-training-install-studio?index=..%2F..android-kotlin-fundamentals#0)
Android Studioのインストール方法。

## 1.2 [Get started](https://developer.android.com/codelabs/kotlin-android-training-get-started#0)
スクリーンに"Hello World"を表示する（だけ）のアプリケーションを作成します。

## 1.3 [Anatomy of Basic Android Project](https://developer.android.com/codelabs/kotlin-android-training-app-anatomy#0)
ボタンをクリックすると1～6の数字が表示される、DiceRollerというアプリケーションを作ります。`Button`、`TextView`など画面部品の配置方法やイベントハンドラ、リスナの作成方法が紹介されています。

## 1.4 [Image resources and compatibility](https://developer.android.com/codelabs/kotlin-android-training-images-compat#0)
1.3で作ったDiceRollerアプリの改善。数字をテキストではなく`Image Resource`を使って画像で表示します。

# 1.5 [Learn to help yourself](https://developer.android.com/codelabs/kotlin-android-training-available-resources#0)
プロジェクトテンプレート（`BasicAcitiviy`）の使用方法、既存のサンプルアプリ（[sunflower](https://github.com/android/sunflower)アプリ）のダウンロードと改修（ランチャーアイコンの変更）について。

***

# レッスン2: レイアウト

> レッスン 2 では、Android Studio Layout Editor を使って、リニア レイアウトと制約レイアウトを作成する方法を学びます。ユーザー入力を取得して表示する、ユーザーのタップに反応する、ビューの外観と色を変更するアプリを作成します。このレッスンでは、データ バインディングを使って findViewById() メソッドの非効率的な呼び出しを排除する方法についても説明します。

この章ではAboutMeというアプリを作りながらレイアウトの基礎を学んでいきます。
作るアプリはこんな感じ。
![02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/c82658b5-7196-5665-4c5a-8b8fcc202b57.gif)



## 2.1 [LinearLayout using the Layout Editor](https://developer.android.com/codelabs/kotlin-android-training-linear-layout?index=..%2F..android-kotlin-fundamentals#0)
`LinearLayout`上に`ScrollView`を乗っけたアプリを作ります。

## 2.2 [Add user interactivity](https://developer.android.com/codelabs/kotlin-android-training-interactivity#0)
2.1で作った`ScrollView`と`TextView`のアプリの改修。`EditText`と`Button`を実装してイベントの制御方法を学びます。
結構前までの内容と重複している部分が多く退屈かもしれませんが、画面部品の`visibility`等の状態遷移についても触れられているのでハンズオンだけでも触れておくと良いかも（英語読まなくても内容分かると思います）。


## 2.3 [ConstraintLayout using the Layout Editor](https://developer.android.com/codelabs/kotlin-android-training-constraint-layout#0)
`ConstraintLayout`の使い方。このコードラボではアプリを作るっていうか、`ConstraintLayout`で画面部品をどのように相対的に配置するかを学びます。
初学者の方にはなかなかイメージが掴みにくいレイアウトかもしれませんが、使いこなせるようになるとその後の生産性が向上することは間違いないのでよく読み込むと良いでしょう。

## 2.4 [Data binding basics](https://developer.android.com/codelabs/kotlin-android-training-data-binding-basics#0)
`findViewById()`に代わる`DataBinding`を学びます。
**初学者の方はこのコードラボは是非しっかり読んでおきましょう。**
続く`ViewModel`や`LiveData`の基礎となります。
2.2で作ったアプリをいじる形で進みますが、そこまでのコードはDLできます。まぁハンズオンで実装しておいた方が理解は早いかも。
説明も結構分かりやすいです。

***

# レッスン3：ナビゲーション

> レッスン 3 では、アプリ内に便利なナビゲーションを作成する方法を学習します。フラグメントを作成してアプリに追加してから、Android Studio ナビゲーション グラフを使ってアプリにナビゲーションを追加します。ナビゲーション ドロワーとオプション メニューをアプリに追加し、アプリのバックスタックを使用して、システムの [戻る] ボタンの表示先を変更します。最後に、アプリ内から外部のアクティビティを呼び出す方法を学習します。

画面遷移をコントロールするための`Navigation`の使い方について学びます。
AndroidTriviaアプリという、Androidに関するクイズを解いていくアプリを段階的に作成します。
![03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/cb4b63f4-7514-5ade-5f30-3b502bf7700c.gif)


## [3.1 Create a fragment](https://developer.android.com/codelabs/kotlin-android-training-create-and-add-fragment?index=..%2F..android-kotlin-fundamentals#0)

`Fragment`をプロジェクトに追加します。ここではアイテムを追加するだけ。

## [3.2 Define navigation paths](https://developer.android.com/codelabs/kotlin-android-training-add-navigation#0)

複数の画面をプロジェクトに追加していきます。画面遷移は`Navigaiton`によりコントロールされます。
またAndroidの`Back Button`（戻るボタン）の制御方法についてもあわせて触れられています。初めのころは結構戸惑うポイントだとも思うので、ここはしっかり目に読んでおくと良いかも。
<img width="600" alt="0302.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/4c4deb78-01cf-8c98-8a76-3a40e8fd0d1b.png">
（コードラボ：https://developer.android.com/codelabs/kotlin-android-training-add-navigation?hl=ja#5 より）

## 3.3 [Start an external Activity](https://developer.android.com/codelabs/kotlin-android-training-start-external-activity#0)

引き続きアプリの改修に取り組みます。
ここではクイズの結果を他のアプリに引き渡し、共有する機能を実装します。そのために必要な`Fragment`への`Bundle`の渡し方、`Safe Args`の使い方、そして`Implicit Intent`（暗黙的インテント）の概要について学びます。

***

# レッスン4：アクティビティとフラグメントのライフサイクル

> レッスン 4 では、アクティビティとフラグメントのライフサイクルと、複雑なライフサイクルの状態に対処する方法を学習します。Android のライフサイクルに関連するバグをいくつか含むスターター アプリを使用します。アプリのライフサイクル イベントをよく把握するために、アプリへのロギング機能の追加、アプリに含まれるバグの修正、アプリへの拡張機能の追加を行います。また、Android Jetpack のライフサイクル ライブラリも学習します。このライブラリには整然とした管理しやすいコードがあり、ライフサイクル イベントを管理するのに役立ちます。

## 4.1 [Lifecycles and logging](https://developer.android.com/codelabs/kotlin-android-training-lifecycles-logging?index=..%2F..android-kotlin-fundamentals#0)

このレッスンはコードラボが一つだけ。ラクチンですね。
Dessert Clickerというなんだか良く分からないアプリを作りますが、まぁアプリはどうでもよくて、`Activity`や`Fragment`がInitialize（生成）～Destory（破棄）されるまでにどのように（どの順番で）コールバックのメソッドが呼び出されるかが本題です。
`MainActibiy.kt`に`onResume()`や`onDestory()`などのメソッドを実装し、その中にログ出力処理を組み込むことでどのような順番で各メソッドが動くのか理解するのがこのコードラボの論旨です。
<img width="300" alt="0401.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/69961cfe-4686-4dd6-03cf-5059d3cb1a4b.png">
（https://developer.android.com/codelabs/kotlin-android-training-lifecycles-logging?hl=ja#2 より）

***

# レッスン5：アーキテクチャ コンポーネント

> レッスン 5 では、ViewModel オブジェクトと LiveData オブジェクトの使用方法を学習します。ViewModel オブジェクトを使って、画面の回転などの設定変更後にデータを引き継ぐ方法を学習します。アプリの UI データをカプセル化された LiveData に変換し、LiveData の値が変更されたときに通知されるオブザーバー メソッドを追加します。
> また、LiveData と ViewModel をデータ バインディングと統合すると、アプリのフラグメントを使って情報を中継することなく、レイアウト内のビューが ViewModel オブジェクトと直接通信できるようになります。この方法によりコードを簡略化できるので、UI コントローラでクリック ハンドラを使用する必要がなくなります。

レッスンを通してGuessTheWardというアプリを作ります。
お題として表示された単語をプレイヤーはその単語を用いずにジェスチャ等で演じ、相手がお題を言い合てられたらポイントが加算、間違えたら減算。
ゲームが終了したら最終的なスコアを表示する画面に遷移します。
![05.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/d5106fcd-92e5-6696-8934-6f9ffd58474b.gif)


## 5.1 [ViewModel](https://developer.android.com/codelabs/kotlin-android-training-view-model?index=..%2F..android-kotlin-fundamentals#0)

`ViewModel`と`ViewModelFactory`を実装します。あらかじめ用意されたコードに手を入れていく形です。
前半は`Activity`や`Fragment`などの`UI controller`に対し`ViewModel`とはどのようなものなのか、またあるべきデザインパターン（`MVVM`）の解説が中心です。
Androidの[app architecture guidelines](https://developer.android.com/jetpack/guide?hl=ja)はこのアーキテクチャをを推奨しているので、しっかりと読んで理解しましょう。

## 5.2 [LiveData and LiveData observers](https://developer.android.com/codelabs/kotlin-android-training-live-data#0)

つぎは`LiveData`について。`LiveData`を使うことにより、例えば画面の`TextView`を明示的に書き換えなくても`LiveData`として定義されたデータを更新するだけで画面上に反映できるようになります。また`MutableLiveData`と`LiveData`の違いについての解説もありますが、この辺りはセキュアなコードを実現するうえでとても大切な点ですね。

## 5.3 [Data binding with ViewModel and LiveData](https://developer.android.com/codelabs/kotlin-android-training-live-data-data-binding#0)

さらにアプリを発展させていきます。これまでは`activity.kt`クラスを経由して`View`と`ViewModel`を結び付けていましたが、両者を直接`DataBinding`で接合する方法を学びます。イベントハンドラも不要になりますね。
コードラボでも紹介されていますが、この書き方をするとイベントとリスナは自動生成されるクラスで接合されます。そのため例えば`View`（xml）側で呼び出すメソッドのスペルをミスったとしてもエディタ上はエラーとして表示されず、コンパイル時にエラーが吐かれます。あれ、どこにバグがあるんだ？　って気づきにくい点なので注意しましょう。

## 5.4 [LiveData transformations](https://developer.android.com/codelabs/kotlin-android-training-live-data-transformations#0)

`LiveData`を他の型やフォーマットに変換する方法として、`Transformations.map()`が紹介されています。
ここでは60,000ミリ秒から0ミリ秒までの`CountDownTimer`の`LiveData`、`MM:SS`フォーマットに変換する方法を学びます。

***

# レッスン6：Room データベースとコルーチン

> レッスン 6 では、Room データベース ライブラリの使用方法について説明します。Room は、データベースのセットアップと設定に関する多数の処理を行い、データベースを操作するためのコードを簡素化します。Kotlin コルーチンを使ってデータベース操作をメインスレッドから移動する方法と、ViewModel と LiveData をアプリ ナビゲーションで使う方法を学習します。

毎日の睡眠の開始と終了、そして睡眠の質を記録するTrackMySleepQualityというアプリを作っていきます。
毎日の睡眠の記録……ということでアプリ内でデータの保持が必要ですね。この章ではDB操作を`Room`から行います。
従来の？やり方である`DBヘルパークラス`での実装方法や`SQLite`の解説はありません。
![06.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/cdd43b67-65b0-f9e5-f2ea-5651f6f47bf5.gif)


## 6.1 [Create a Room Database](https://developer.android.com/codelabs/kotlin-android-training-room-database#0)

とりあえず`Room`のさわりから。`エンティティ`、`DAO`、そして`Room`データベースクラスを作成します。
このトレーニングは最終的には`MVVM+Repository`というデザインパターンでアプリを実装することになります。
`Room`は`ViewModel`と並びその根幹となる要素技術ですので、概念を含め時間をかけても理解すべき内容でしょう。

## 6.2 [Coroutines and Room](https://developer.android.com/codelabs/kotlin-android-training-coroutines-and-room#0)

`ViewModel`に6.1.で作成した`Room`データベースを埋め込んでいきます。またDBの読み書きをする際は`コルーチン`の利用が推奨されていますが、このコードラボでだいぶ詳しく解説されています。
そして`ViewModel`から各種アプリの処理を実装してきます。

## 6.3 [Use LiveData to control button states](https://developer.android.com/codelabs/kotlin-android-training-quality-and-states#0)

続けて画面遷移を実装します。ほぼこれまでやったきたことのおさらいってかんじですね。


***

# レッスン7：RecyclerView

> レッスン 7 では、RecyclerView を使ってアイテムのリストとグリッドを効率的に表示する方法について説明します。複雑なリストやグリッドを使う場合の、RecyclerView の効率を高める方法と、コードの管理と拡張を容易にする方法を学習します。RecyclerView のアイテムをクリック可能にする方法を学習します。また、RecyclerView のリストやグリッドに複数のビューホルダーとレイアウトを追加して、たとえば、アプリにヘッダーを追加する方法も学習します。

段々と内容も込み入ってきます。
作成するアプリは前章で作成したTrackMySleepQualityの拡張で、記録を`RecyclerView`で表示する方式に改修するのですが、3章の`Fragment`、5章の`ViewModel`、6章の`Room`の内容をよく理解していないとかなり厳しいです。
ここまで不安という方は一度立ち止まって理解を深めることを強くお勧めします。
![07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/cb42fd2f-9531-c115-4c1f-7d1a33203be6.gif)



## 7.1 [RecyclerView fundamentals](https://developer.android.com/codelabs/kotlin-android-training-recyclerview-fundamentals?index=..%2F..android-kotlin-fundamentals#0)

`RecylceView`の基礎について。`RecylceView`は非常に拡張性の高い画面部品ですが、これまで使っていた`ListView`と比べると手動で設定しなければならない項目も多いです。
このコードラボではその実装方法である`Adapter`と`ViewHolder`が紹介されています。

## 7.2 [DiffUtil and data binding with RecyclerView](https://developer.android.com/codelabs/kotlin-android-training-diffutil-databinding#0)

7.1のコードを改修します。
アプリの見た目、挙動は変わりませんが、`RecyclerView`のデータ更新に便利な`DiffUtil`というユーティリティクラスでリファクタリングをしていきます。

## 7.3 [GridLayout with RecyclerView](https://developer.android.com/codelabs/kotlin-android-training-grid-layout#0)

7.2までの`RecyclerView`は`LinearLayout`を使用していましたが、それを`GridLayout`に変更します。

## 7.4 [Interacting with RecyclerView items](https://developer.android.com/codelabs/kotlin-android-training-interacting-with-items#0)

さらに内容を発展させて、`RecyclerView`に格納されたアイテムへのクリックなどのイベントをどのように受け取るべきかのベストプラクティスについて。
ここでは`ViewModel`側でイベントを処理します。
だいぶややこしくなってきましたが、トレーニングも終盤です。一緒に頑張りましょう。

## 7.5 [Headers in RecyclerView](https://developer.android.com/codelabs/kotlin-android-training-headers#0)

`RecyclerView`に`Header`を載せる方法について紹介されています。

***

# レッスン8：インターネットへの接続

> レッスン 8 では、コミュニティで開発したライブラリを使ってウェブサービスに接続し、データの取得や表示を行う方法について説明します。潜在的なネットワーク エラーに対処する方法と、Glide ライブラリを使って、インターネットから写真を読み込んで表示する方法を学習します。また、RecyclerView を作成し、それを使って画像のグリッドを表示します。

AndroidからWEBのリソースにアクセスする方法を学びます。
前章までに学んだ`LivData`、`ViewModel`、`RecyclerView`を活用しMarsRealEstateというアプリを作成します。
これはその名の通り（？）売り出し中の火星の土地の写真を既存のWEBサービスからとってきて、Gridで表示するというアプリです。
おれも買おうかな。
![08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/97b51931-2800-864f-d599-4e26368ceaa2.gif)


## 8.1 [Getting data from the internet](https://developer.android.com/codelabs/kotlin-android-training-internet-data#0)

とりあえず実際にWEBサーバーに接続してデータを取ってくるまで。
なお火星の土地データは`json`形式で`REST`で受信します。`REST`クライアントは`Retrofit`というライブラリを利用して作成し、`Moshi`というライブラリで`json`をParseする方法が紹介されています。
受信した`json`のレコード数を`TextView`で表示します。

## 8.2 [Loading and displaying images from the Internet](https://developer.android.com/codelabs/kotlin-android-training-internet-images#0)

受信した`json`に含まれている画像データを`RecylerView`のGridに表示します。`Glide`というライブラリを用いて画像のダウンロード、バッファ、でコード、キャッシュを行います。便利ですね。
このコードラボでキャッシュした画像をGridに表示します。
その他にもローディング時のアニメーションの実装方法がチラっと紹介されていたり、役立ちそうなことが多くて楽しいです。

## 8.3 [Filtering and detail views with internet data](https://developer.android.com/codelabs/kotlin-android-training-internet-filtering#0)

最後に、Gridで表示された画像をタップすると詳細のページに遷移する機能を付け足します。
ついでに`OverflowMenu`から`RecyclerView`に表示するアイテムをフィルターする機能も追加するんですが、個人的にこのベストプラクティスを知れたのは良かったです。なるほどね。
あとは画面遷移の際は`Bundle`ではなく`Parcelable`を用います。

***

# レッスン9：リポジトリ

> レッスン 9 では、リポジトリを追加してデータレイヤーを抽象化し、Android Kotlin アプリの他のアプリにクリーンな API を提供する方法について説明します。また、WorkManager を使って、バックグラウンド タスクを効率的かつ最適化された方法でスケジュール設定する方法についても説明します。
> (公式サイト：https://developer.android.com/courses/kotlin-android-fundamentals/overview?hl=ja より)

日本語が何だか分かりにくいですね……。
`リポジトリ`と言ってもGitのアレではないです。ここでいうのは`Repository Patter`というAndroidにおけるデザインパターンの一種です。
簡単に言えばインターネットなどのデータソースとアプリとを切り離す構成ですが、これによりネットワーク環境のないところでもキャッシュしたデータをもとにアプリを動作させることができます。
今では当たり前の技術ですが、いざ自分で実装しようとするとその大変さが何だか伝ってきますね。
DevBytesというアプリを作ります。
![09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/bfb4f639-e913-a256-e100-04ce79424979.gif)


## 9.1 [Repository](https://developer.android.com/codelabs/kotlin-android-training-repository#0)

インターネットから取得したデータを`Room`にキャッシュする方法について学びます。そしてそれを読み込む方法について。

## 9.2 [WorkManager](https://developer.android.com/codelabs/kotlin-android-training-work-manager#0)

表題の通り`WorkManager`について。
多くのアプリはバッググラウンドで様々な処理を行っていますが、`WorkManager`はそれらの処理の最適化を図ってくれます。

***

# レッスン10：すべてのユーザー向けの設計

> このレッスンでは、Android アプリ設計の基本について説明します。テーマとスタイル、マテリアル デザインのほか、誰もがアプリを簡単に使用できるようにする方法を紹介します。
> (公式サイト：https://developer.android.com/courses/kotlin-android-fundamentals/overview?hl=ja より)

いよいよ最後のレッスンです！
この章は他とは少し毛色が違い、主にデザインやユーザビリティに関する技法やテクニックについて、各論的に学びます。
サンプルコードではこれまでに学んだ`ViewModel`や`Room`がふんだんに使われていますが、この章の内容ではないので復習は別途しておきましょう。
GDG-finderというアプリをリファクタリングしていきます。
![10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/0b53e69f-d558-e172-fd7f-e81139a0a405.gif)


## [10.1 Styles and themes](https://developer.android.com/codelabs/kotlin-android-training-styles-and-themes#0)

Androidのスタイリングシステムの基礎、`attribute`、`style`、`theme`の使い方について。
Androidのスタイリングシステムは`View`を頂点としたピラミッド構造になっています。なのでどのレイヤーでデザインを適用するかを考える必要がある、という内容です。

## 10.2 [Material Design, dimens, and colors](https://developer.android.com/codelabs/kotlin-android-training-material-design-dimens-colors#0)

いよいよ出ました`Material Design`。と言ってもここでは深く踏み込まず、`FloatingActionButton`を実装するだけです。
あとアプリのテーマカラーを決めるのに便利な[COLOR TOOL](https://material.io/resources/color/)というサイトが紹介されています。
これは便利。

## 10.3 [Design for everyone](https://developer.android.com/codelabs/kotlin-android-training-design-for-everyone#0)

世界にアプリを発信していくには様々な言語やバックグラウンドを持った方々が使うことも考えなければなりません。
ここではRTL言語（アラビア文字など右から左に読む言語）、[ユーザー補助検証ツール](https://play.google.com/store/apps/details?id=com.google.android.apps.accessibility.auditor)によるユーザービリティの改善、ナイトモードへの対応方法などが個別に紹介されています。


# まとめ

以上、大変お疲れさまでした！
正直全量をこなすにはかなりの労力が必要なトレーニングです。
しかも7章の`RecyclerView`のあたりから内容もだいぶ複雑になってきて、復習の時間も必要でしょう。

しかしここで触れられた内容を十分に理解していればその後の生産性もグッと上がることは間違いありませんし、何より公式が推奨するベストプラクティスをハンズオンという形式で半ば強制的に押し付けられるのは非常に良いトレーニングだとも思います。

自分も100％ものにしているかと言われればスミマセン結構怪しいところあるんですが、公式のリファレンスなんかも参照しつつともに頑張っていきましょう。

ではでは。