0Pricing
Kotlin Academy · レッスン

Sealed ClassによるUI状態のモデル化

sealed classを使ってLoading、Success、ErrorのUI状態を表現します。

「Sealed ClassによるUI状態のモデル化」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。

UI の状態の問題

UI 画面には、読み込み中、データ表示中、エラー表示中、空の状態など、複数の状態があります。これらをブール値(isLoading、hasError)で管理すると壊れやすくなります。sealed class がこの問題を解決します。

古典的なブール値地獄

個別のブール値を使うと、あり得ない状態が生じます。
// Fragile: isLoading=true AND hasError=true is invalid
var isLoading = false
var hasError = false
var data: List<Item>? = null
// 8 combinations, most of which are invalid!

sealed 状態:有効な状態だけ

sealed class を使うと、不正な状態を表現できないようにできます。
sealed class UiState<out T>
object Loading : UiState<Nothing>()
data class Success<T>(val data: T) : UiState<T>()
data class Error(val message: String, val retryable: Boolean = true) : UiState<Nothing>()
object Empty : UiState<Nothing>()

状態に基づくレンダリング

各状態に応じた正しい UI をレンダリングするには、when を使用してください。
fun render(state: UiState<List<Item>>) = when (state) {
    Loading -> showProgressBar()
    is Success -> showItems(state.data)
    is Error -> showError(state.message, state.retryable)
    Empty -> showEmptyView()
}

ViewModel による状態の発行

ViewModel は StateFlow を通じて sealed 状態を発行します。
class ItemViewModel : ViewModel() {
    private val _state = MutableStateFlow<UiState<List<Item>>>(Loading)
    val state: StateFlow<UiState<List<Item>>> = _state

    fun loadItems() = viewModelScope.launch {
        _state.value = Loading
        _state.value = try {
            Success(repository.getItems())
        } catch (e: Exception) {
            Error(e.message ?: "Unknown error")
        }
    }
}

内部コンテンツを持つ状態の合成

任意のデータ型を扱うには、ジェネリックな sealed 状態を使用してください。
fun <T> loading(): UiState<T> = Loading
fun <T> success(data: T): UiState<T> = Success(data)
fun <T> error(msg: String): UiState<T> = Error(msg)

ページネーション状態の例

sealed class は、ページ分割されたリストの状態を自然にモデル化できます。
sealed class PageState
object Idle : PageState()
object FirstLoad : PageState()
data class Content(val items: List<Item>, val hasMore: Boolean) : PageState()
data class LoadingMore(val items: List<Item>) : PageState()
data class Error(val items: List<Item>?, val msg: String) : PageState()

状態の変換

他のケースに触れずに、成功状態だけを変換します。
fun <T, R> UiState<T>.mapData(transform: (T) -> R): UiState<R> = when (this) {
    is Success -> Success(transform(data))
    is Error -> this
    Loading -> Loading
    Empty -> Empty
}

sealed 状態のテスト

状態は、どのバリアントが発行されたかを確認するだけで簡単にテストできます。
@Test
fun testLoadingState() {
    viewModel.loadItems()
    assertEquals(Loading, viewModel.state.value)
}
@Test
fun testSuccessState() {
    viewModel.setData(listOf(item))
    assert(viewModel.state.value is Success)
}

統合状態と複数のフロー

同期を維持する必要がある複数の個別フローよりも、1つの sealed 状態フローの方がすっきりします。
// Fragile: two flows must stay in sync
val loading = MutableStateFlow(false)
val error = MutableStateFlow<String?>(null)

// Clean: one sealed state
val state = MutableStateFlow<UiState<List<Item>>>(Loading)

状態へのメタデータの追加

sealed サブタイプには、関連するメタデータを持たせることができます。
data class Error(
    val message: String,
    val code: Int = 0,
    val retryable: Boolean = true,
    val timestamp: Long = System.currentTimeMillis()
) : UiState<Nothing>()

クイックチェック

sealed class で UI の状態をモデル化すると、どのような主要な問題を解決できますか?

まとめ

UI の状態は sealed class でモデル化します。Loading、Success(data)、Error(message)、Empty を使用します。各ケースをレンダリングするには when を使用してください。sealed 型を持つ1つの StateFlow は、複数のブール値フラグよりも優れています。次は sealed 階層のネストです。

よくある質問

「Sealed ClassによるUI状態のモデル化」レッスンは無料ですか?

はい。「Sealed ClassによるUI状態のモデル化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。

「Sealed ClassによるUI状態のモデル化」で何を学びますか?

sealed classを使ってLoading、Success、ErrorのUI状態を表現します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Kotlin Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「Sealed ClassによるUI状態のモデル化」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このKotlin Academyレッスンでコードを書いて実行できますか?

はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. sealed classとsealed interface:使い分け
  2. sealed階層を網羅するwhen
  3. Sealed ClassによるUI状態のモデル化
  4. Sealed階層のネストと組み合わせ
← Kotlin Academyに戻る