Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import androidx.compose.foundation.background
- import androidx.compose.foundation.focusable
- import androidx.compose.foundation.layout.Box
- import androidx.compose.foundation.layout.BoxScope
- import androidx.compose.foundation.layout.fillMaxSize
- import androidx.compose.foundation.layout.size
- import androidx.compose.material3.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.runtime.DisposableEffect
- import androidx.compose.runtime.LaunchedEffect
- import androidx.compose.runtime.getValue
- import androidx.compose.runtime.mutableStateOf
- import androidx.compose.runtime.remember
- import androidx.compose.runtime.setValue
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.graphics.Color
- import androidx.compose.ui.platform.LocalContext
- import androidx.compose.ui.semantics.LiveRegionMode
- import androidx.compose.ui.semantics.contentDescription
- import androidx.compose.ui.semantics.liveRegion
- import androidx.compose.ui.semantics.semantics
- import androidx.compose.ui.tooling.preview.Preview
- import androidx.compose.ui.unit.Dp
- import androidx.compose.ui.unit.dp
- import kotlinx.coroutines.delay
- @Composable
- fun FullScreenLoading(
- isLoading: Boolean,
- modifier: Modifier = Modifier,
- iconSize: Dp = 32.dp,
- content: @Composable BoxScope.() -> Unit
- ) {
- val loadingContentCd = "Loading"
- val finishedLoadingCd = "Finished Loading"
- var finishedLoading by remember { mutableStateOf(false) }
- // option 1: works for normal usages, but not when compose screen is closed quickly after loading is finished (isLoading=false state is not reached before navigating away)
- // possible fix for that is to delay navigating away shortly after loading is finished (~350ms delay seems to be enough on my test devices, but not 325ms.. not ideal since it could required different delays for different devices)
- if (finishedLoading) {
- Text(text = " ", modifier = Modifier
- .focusable(false)
- .semantics {
- liveRegion = LiveRegionMode.Assertive
- contentDescription = finishedLoadingCd
- }
- )
- }
- Box(modifier.fillMaxSize()) {
- content()
- if (isLoading) {
- Box(
- modifier = Modifier
- .fillMaxSize()
- .background(Color.White.copy(alpha = 0.8f))
- //.simpleClickable { Timber.i("FullScreenLoading clicked") }
- .semantics {
- liveRegion = LiveRegionMode.Assertive
- contentDescription = loadingContentCd
- }
- ) {
- // Loading icon goes here
- Box(
- modifier = Modifier
- .size(iconSize)
- .align(Alignment.Center)
- .background(Color.Red)
- )
- val context = LocalContext.current
- DisposableEffect(context) {
- onDispose {
- // option 1:
- finishedLoading = true
- // option 2: use announceForAccessibility through host activity
- // announceForAccessibility is not recommended even for View system anymore and Compose won't have support for it: https://issuetracker.google.com/issues/172590945
- // context.findActivity().getRootView().announceForAccessibility(finishedLoadingCd)
- }
- }
- }
- }
- }
- }
- @Preview
- @Composable
- private fun FullScreenLoadingPreview() {
- var isLoading by remember { mutableStateOf(true) }
- LaunchedEffect(Unit) {
- while (true) {
- delay(3000)
- isLoading = !isLoading
- }
- }
- FullScreenLoading(isLoading = isLoading) {
- Text(text = "Content")
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement