Jetpack Compose ローディングスピナー

SwiftUI の ZStack 相当

Jetpack Compose では Box です。

ローディングスピナーを画面全体に重ねる場合はこんな感じになります。

SwiftUIでいうと

ZStack {
    MainScreen()

    if isLoading {
        Color.black.opacity(0.3)
            .ignoresSafeArea()

        ProgressView()
    }
}

とほぼ同じです。


ViewModelに持たせるのがおすすめ

TableDataStore に

var isLoading by mutableStateOf(false)
    private set

を追加して、

suspend fun load(...) = withContext(Dispatchers.IO) {
    isLoading = true

    try {
        ...
    } finally {
        isLoading = false
    }
}

とすると、

if (tableDataStore.isLoading) {
    ...
}

で簡単に表示できます。


タップも無効化したい場合

背景を半透明にしているだけだと、下の画面を押せてしまうことがあります。

完全にモーダル化するなら、

のようにタップを吸収させます。


個人的には今回のケースなら、AppRoot() の一番外側を

Box(
    modifier = Modifier.fillMaxSize()
)

にして、

if (tableDataStore.isLoading) {
    LoadingOverlay()
}

を重ねる構成が SwiftUI の ZStack + ProgressView にかなり近くて移植しやすいと思います。さらに Android らしくするなら、保存中は "暗号化中..."、読込中は "復号中..." のテキストも付けるとユーザー体験が良くなります。

タイトルとURLをコピーしました