Android Kotlin基礎講座 06.3:Livedataを使ってボタンの状態をコントロールする

Android Kotlin基礎講座

タスク:睡眠の質を記録する

このタスクでは、睡眠の質を記録し、SleepTrackerFragmentに戻るようにします。
画面は自動で更新された値をユーザーに表示すべきです。そのためにはViewModelとViewModelFactoryを作成し、SleepQualityFragmentを更新する必要があります。

ステップ1:ViewModelとViewModelFactoryを作成する

  1. sleepqualityパッケージ内にSleepQualityViewModel.ktを作成、または開いてください。
  2. 引数にsleepNightKeyとデータベースを受け取るSleepQualityViewModelクラスを作成してください。SleepTrackerViewModelに行ったのと同じように、ファクトリーからdatabaseを渡す必要があります。またナビゲーションからsleepNightKeyを渡す必要もあります。
class SleepQualityViewModel(
       private val sleepNightKey: Long = 0L,
       val database: SleepDatabaseDao) : ViewModel() {
}
  1. 上記と同じパターンを使ってSleepTrackerFragmentに戻るようにするために、_navigateToSleepTrackerを宣言してください。
    navigateToSleepTrackerとdoneNavigating()を実装してください。
private val _navigateToSleepTracker = MutableLiveData<Boolean?>()

val navigateToSleepTracker: LiveData<Boolean?>
   get() = _navigateToSleepTracker

fun doneNavigating() {
   _navigateToSleepTracker.value = null
}
  1. 睡眠の質を評価用の画像全てが使うことになるクリックハンドラー、onSetSleepQuality()を作成してください。

以前の記事と同じコルーチンパターンを使います。

  • viewModelScope内でコルーチンを立ち上げます。
  • sleepNightKeyを使ってtonightを取得します。
  • 睡眠の質をセットします。
  • データベースを更新します。
  • ナビゲーションをトリガーします。

以下のサンプルコードでは、異なるコンテクスト内にデータベース操作をくくりだすのではなく、全ての作業をクリックハンドラーの中で行わせています。

fun onSetSleepQuality(quality: Int) {
        viewModelScope.launch {
                val tonight = database.get(sleepNightKey) ?: return@launch
                tonight.sleepQuality = quality
                database.update(tonight)
            

            // Setting this state variable to true will alert the observer and trigger navigation.
            _navigateToSleepTracker.value = true
        }
    }
  1. sleepqualityパッケージ内に、SleepQualityViewModelFactory.ktを作成、または開き、SleepQualityViewModelFactoryクラスを以下のように追加してください。このクラスは以前紹介したのと同じボイラープレートコードを利用しています。
    次に進む前にコードを確認しておいてください。
class SleepQualityViewModelFactory(
       private val sleepNightKey: Long,
       private val dataSource: SleepDatabaseDao) : ViewModelProvider.Factory {
   @Suppress("unchecked_cast")
   override fun <T : ViewModel?> create(modelClass: Class<T>): T {
       if (modelClass.isAssignableFrom(SleepQualityViewModel::class.java)) {
           return SleepQualityViewModel(sleepNightKey, dataSource) as T
       }
       throw IllegalArgumentException("Unknown ViewModel class")
   }
}

ステップ2:SleepQualityFragmentを更新する

  1. SleepQualityFragment.ktを開いてください。
  2. onCreateView()内のapplicationの取得の後で、ナビゲーションに付属のargumentsを取得する必要があります。これらのargumentsはSleepQualityFragmentArgs内にあります。これらをbundleから抽出する必要があります。
val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!)
  1. 次に、dataSourceを取得します。
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
  1. dataSourceとsleepNightKeyを渡して、ファクトリーを作成してください。
val viewModelFactory = SleepQualityViewModelFactory(arguments.sleepNightKey, dataSource)
  1. ViewModelの参照を取得してください。
val sleepQualityViewModel =
       ViewModelProvider(
               this, viewModelFactory).get(SleepQualityViewModel::class.java)
  1. ViewModelをバインディングオブジェクトに追加してください。(バインディングオブジェクトに関するエラーが表示されても、ここでは無視してください)
binding.sleepQualityViewModel = sleepQualityViewModel
  1. オブザーバーを追加してください。インポートを促されたら、androidx.lifecyle.Observerをインポートしてください。
sleepQualityViewModel.navigateToSleepTracker.observe(this, Observer {
   if (it == true) { // Observed state is true.
       this.findNavController().navigate(
               SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment())
       sleepQualityViewModel.doneNavigating()
   }
})

ステップ3:レイアウトファイルを更新し、アプリを起動する

  1. fragment_sleep_quality.xmlレイアウトファイルを開いてください。<data>ブロック内にSleepQualityViewModel用の変数を追加してください。
<data>
       <variable
           name="sleepQualityViewModel"
           type="com.example.android.trackmysleepquality.sleepquality.SleepQualityViewModel" />
   </data>
  1. 6つある睡眠の質の画像それぞれに、クリックハンドラーを以下のように追加してください。最後の評価値はそれぞれの画像に合わせて変更してください。
android:onClick="@{() -> sleepQualityViewModel.onSetSleepQuality(5)}"
  1. プロジェクトをクリーンアップしてリビルドしてください。バインディングオブジェクトに関するエラーも解決されているはずです。もしされていない場合、キャッシュをクリア(File > Invalidate Caches / Restart)して、アプリをリビルドしてください。

エラーがないことを確認し、アプリが起動できたら、睡眠の質を記録できるようになっていることを確認してください。

おめでとうございます!コルーチンを使った完全あRoomデータベースアプリが完成しました。

コメント

プロフィール

プロフィール
コードラボJP

大学卒業後SEに就職、現在は退職しフリーランスとして活動中。
『初心者でも挫折せずに一人でプログラミングを学べる』をモットーに、コードラボJPを開設
お問い合わせ等はcodelabsjp@gmail.comまで

コードラボJPをフォローする
タイトルとURLをコピーしました