Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetpack compose - how do I refresh a screen when app returns to foreground

I need to automatically refresh an Android Compose screen when the app returns to the foreground.

I have an that requires permissions and location services.

If the user has switched any of these off a list is drawn of the items that need to be changed. When the user goes to Settings and the app returns to the foreground I would like the list to refresh to reflect the changes.

I am using Compose and Compose navigation. I have looked and I can't figure out the equivalent of onResume lifecycle event that could be used to trigger the refresh.

Any ideas would be gratefully received as I am at a loss.

like image 445
William Avatar asked Mar 09 '21 12:03

William


2 Answers

I slightly improved @JojoIV answer and made it flat usage without callback like you observe LiveData in compose what @Abdelilah El Aissaoui answered

@Composable
fun Lifecycle.observeAsState(): State<Lifecycle.Event> {
    val state = remember { mutableStateOf(Lifecycle.Event.ON_ANY) }
    DisposableEffect(this) {
        val observer = LifecycleEventObserver { _, event ->
            state.value = event
        }
        [email protected](observer)
        onDispose {
            [email protected](observer)
        }
    }
    return state
}

and then usage

@Composable
fun SomeComposable() {
   val lifecycleState = LocalLifecycleOwner.current.lifecycle.observeAsState()
   val state = lifecycleState.value
   // or val lifecycleState by LocalLifecycleOwner.current.lifecycle.observeAsState()
  // will re-render someComposable each time lifecycleState will change
}
like image 121
Arsenius Avatar answered Oct 24 '22 01:10

Arsenius


I came up with this:

@Composable
fun OnLifecycleEvent(onEvent: (owner: LifecycleOwner, event: Lifecycle.Event) -> Unit) {
    val eventHandler = rememberUpdatedState(onEvent)
    val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current)
    
    DisposableEffect(lifecycleOwner.value) {
        val lifecycle = lifecycleOwner.value.lifecycle
        val observer = LifecycleEventObserver { owner, event ->
            eventHandler.value(owner, event)
        }

        lifecycle.addObserver(observer)
        onDispose {
            lifecycle.removeObserver(observer)
        }
    }
}

It seems to work just fine. But there may be some issues in some cases so be careful.
It is also possible that there is some redundant code.

Usage:

OnLifecycleEvent { owner, event ->
    // do stuff on event
    when (event) {
        Lifecycle.Event.ON_RESUME -> { /* stuff */ }
        else                      -> { /* other stuff */ }
    }
}
like image 48
JojoIV Avatar answered Oct 24 '22 01:10

JojoIV