Android Kotlin基礎講座 06.3:Livedataを使ってボタンの状態をコントロールする
目次
タスク:ナビゲーションを追加する
この記事ではフラグメントとナビゲーションファイルを使ってのナビゲーションの実装方法は既に知っているものと仮定します。ですので作業量を減らすために、ナビゲーション実装コードは既に含まれています。
ステップ1:コードを調べる
- 前回の記事を完了している方はそちらのコードを引き続きお使いいただけます。そうでない場合は、スターターコードをダウンロードしてください。
- スターターコード内のSleepQualityFragmentを開いてください。このクラスはレイアウトをインフレートし、applicationを取得、binding.roodを返します。
- navigation.xmlをデザインエディターで開いてください。SleepTrackerFragmentからSleepQualityFragmentへのナビゲーションがあるのがわかります。またSleepQualityFragmentからSleepTrackerFragmentに再び戻れるようにもなっています。

- navigation.xmlのコードを調べてみましょう。
特にsleepNightKeyと名付けられているargumentを探してください。
ユーザーがSleepTrackerFragmentからSleepQualityFragmentに遷移する際、アプリは更新が必要なデータ用のsleepNightKeyをSleepQualityFragmentに渡します。
ステップ2:睡眠の質計測用のナビゲーションを追加する
ナビゲーショングラフには既にSleepTrackerFragmentからSleepQualityFragmentにつながるパスが含まれています。しかし、フラグメントからフラグメントに遷移させるためのクリックハンドラーはまだコーディングされていません。ViewModel内にそのコードを追加していきます。
クリックハンドラー内で、別の遷移先にナビゲートさせたい時に変化するLiveDataを設定します。フラグメントがこのLiveDataを監視します。このLiveDataが変化すると、フラグメントは遷移先に遷移し、ビューモデルに遷移が完了したことを通知します。その後LiveDataはもとの状態に戻ります。
- SleepTrackerViewModelを開いてください。ユーザーがStopボタンをタップしたときに、アプリがSleepQualityFragmentに遷移し、睡眠の質を収集できるようにするために、ナビゲーションを追加する必要があります。
- SleepTrackerViewModel内で、SleepQualityFragmentに遷移させたい時に変化するLiveDataを作成します。ViewModelに対して、取得可能なLiveDataのみを公開するためにカプセル化します。
クラス内のトップレベル(他の括弧の内側でないこと)であればどこでもいいので、以下のコードを追加してください。
private val _navigateToSleepQuality = MutableLiveData<SleepNight>()
val navigateToSleepQuality: LiveData<SleepNight>
get() = _navigateToSleepQuality
- ナビゲーションのトリガーとなる変数をリセットする関数、doneNavigating()を追加してください。
fun doneNavigating() {
_navigateToSleepQuality.value = null
}
- StopボタンのクリックハンドラーであるonStopTracking()の中に、SleepQualityFragmentへのナビゲーションのトリガーを追加します。この関数のlaunch{}ブロック内の最終行で_navigateToSleepQuality変数を設定してください。この変数がnightデータに設定されていることを確認してください。この変数が値を持っているとき、アプリはSleepQualityFragmentに遷移し、nightを渡します。
_navigateToSleepQuality.value = oldNight
- SleepTrackerFragmentはアプリがいつナビゲートするべきか知るために、_navigateToSleepQualityを監視する必要があります。SleepTrackerFragment内のonCreateView()に、navigateToSleepQuality用のオブザーバーを追加してください。
androidx.lifecycle.Observerをインポートしてください。
sleepTrackerViewModel.navigateToSleepQuality.observe(this, Observer {})

- observer()ブロック内で、ナビゲートと現在の夜のIDを渡し、doneNavigating()を呼び出します。もしインポートの候補が複数ある場合は、androidx.navigation.fragment.findNavControllerをインポートしてください。
night ->
night?.let {
this.findNavController().navigate(
SleepTrackerFragmentDirections
.actionSleepTrackerFragmentToSleepQualityFragment(night.nightId))
sleepTrackerViewModel.doneNavigating()
}
- ビルドしてアプリを起動してください。Startボタンをタップしたのち、Stopボタンをタップしてください。SleepQualityFragment画面に移動します。戻るためにはシステムの戻るボタンを押してください。