🌀

Jetpack Compose 3秒だけ処理

2024/05/11に公開2

🤔やってみたいこと

Jetpack Composeで、ボタンを押すと3秒間だけローディングをしたいユースケースがある。 必要な機能を実装するために実験するためのコード書いてみた。

🚀やってみたこと

CoroutineScopeとdelayの中に3秒後にローディング処理を記述するとできた🙌
HomeScreenというページを作成して、こちらでボタンを押すと3秒間ローディングする処理を作れば実現できる。

package com.junichi.yourbalance.views

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@Composable
fun HomeScreen() {
    var loading by remember { mutableStateOf(false) }

    Button(onClick = {
        loading = true
        CoroutineScope(Dispatchers.Main).launch {
            delay(3000L)
            loading = false
        }
    }, enabled = !loading) {
        Text("Start loading")
    }

    if (loading) {
        Box(
    modifier = Modifier
) {
        CircularProgressIndicator(
            modifier = Modifier.width(64.dp),
            color = MaterialTheme.colorScheme.secondary,
            trackColor = MaterialTheme.colorScheme.surfaceVariant,
        )
}
    }
}

実験用なので見た目は良くないですが💦


🙂最後に

画面遷移するときに、遅延処理があった方が良いかなと思って、ローディングする処理を作ってみました。もしかしたらいらないかもしれないですが😅

https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/delay.html
https://developer.android.com/develop/ui/compose/components/progress

Discussion

てべすてんてべすてん

CoroutineScope(Dispatchers.Main) ではなく rememberCoroutineScope() を使用した方が良さそうな気がしました👀 (こちらはComposition抜けたタイミングでキャンセルされるはずなので)

    val scope = rememberCoroutineScope()
    Button(onClick = {
        loading = true
-       CoroutineScope(Dispatchers.Main).launch {
+       scope.launch {
            delay(3000L)
            loading = false
        }
    }, enabled = !loading) {
        Text("Start loading")
    }
JboyHashimotoJboyHashimoto

てべすてんさんご指摘ありがとうございました!
こちらに修正しても動きました😅
Kotlinは勉強中でしてまだわからないことが多いですね。

HomeScreen.kt
package com.junichi.delayindicator

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import androidx.compose.runtime.rememberCoroutineScope

@Composable
fun HomeScreen() {
    val scope = rememberCoroutineScope()
    var loading by remember { mutableStateOf(false) }

    Button(onClick = {
        loading = true
        scope.launch {
            delay(3000L)
            loading = false
        }
    }, enabled = !loading) {
        Text("Start loading")
    }

    if (loading) {
        Box(
            modifier = Modifier
        ) {
            CircularProgressIndicator(
                modifier = Modifier.width(64.dp),
                color = MaterialTheme.colorScheme.secondary,
                trackColor = MaterialTheme.colorScheme.surfaceVariant,
            )
        }
    }
}