Guillermo
Necesito actualizar automáticamente una pantalla de Redacción de Android cuando la aplicación vuelve al primer plano.
Tengo una que requiere permisos y servicios de ubicación.
Si el usuario ha desactivado alguno de estos, se dibuja una lista de los elementos que deben cambiarse. Cuando el usuario va a Configuración y la aplicación vuelve al primer plano, me gustaría que la lista se actualice para reflejar los cambios.
Estoy usando Redactar y Redactar navegación. He buscado y no puedo encontrar el equivalente del evento del ciclo de vida onResume que podría usarse para activar la actualización.
Cualquier idea sería recibida con gratitud ya que estoy perdido.
Jojo IV
Se me ocurrió esto:
@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)
}
}
}
Parece funcionar bien. Pero puede haber algunos problemas en algunos casos, así que tenga cuidado.
También es posible que haya algún código redundante.
Uso:
OnLifecycleEvent { owner, event ->
// do stuff on event
when (event) {
Lifecycle.Event.ON_RESUME -> { /* stuff */ }
else -> { /* other stuff */ }
}
}
-
Un ejemplo de cómo usar esto sería útil
– SagaRock101
1 de enero de 2022 a las 13:46
-
Por qué
lifecycleOwner
tiene que cambiar? ¿No es algo de solo lectura?– salida estándar
4 de julio de 2022 a las 8:22
-
En producción, observamos algunos problemas de bucle en onResume(). es decir, sigue llamando al bloque Lifecycle.Event.ON_RESUME -> { /* cosas */ } en bucles
– Boobalán
7 de febrero a las 18:56
Arsenio
mejoré un poco @JojoIV responda y lo hizo de uso plano sin devolución de llamada como observa LiveData
en componer lo que @Abdelilah El Aissaoui contestada
@Composable
fun Lifecycle.observeAsState(): State<Lifecycle.Event> {
val state = remember { mutableStateOf(Lifecycle.Event.ON_ANY) }
DisposableEffect(this) {
val observer = LifecycleEventObserver { _, event ->
state.value = event
}
this@observeAsState.addObserver(observer)
onDispose {
this@observeAsState.removeObserver(observer)
}
}
return state
}
y luego el uso
@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
}
-
Esta respuesta fue útil cuando se usaba solo reanudar y pausar, pero no iniciar y detener.
– Bam Bam
8 de noviembre de 2022 a las 5:44
-
@bambam ¿por qué es eso?
– Josué Rey
17/11/2022 a las 21:50
-
Imprimir (el
state
antes del regreso) y (elevent
deLifecycleEventObserver
) en el primer fragmento . En mi caso el primero solo llamaba RESUME y PAUSE. No estoy seguro, pero parece que hay una omisión al pasar por el estado de redacción en lugar de pasar el evento de inmediato. Si no se reproduce, haré más pruebas. @JoshuaKing– Bam Bam
18 de noviembre de 2022 a las 2:39
ejemplo del sitio de google
@Composable
fun HomeScreen(
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
onStart: () -> Unit, // Send the 'started' analytics event
onStop: () -> Unit // Send the 'stopped' analytics event
) {
// Safely update the current lambdas when a new one is provided
val currentOnStart by rememberUpdatedState(onStart)
val currentOnStop by rememberUpdatedState(onStop)
// If `lifecycleOwner` changes, dispose and reset the effect
DisposableEffect(lifecycleOwner) {
// Create an observer that triggers our remembered callbacks
// for sending analytics events
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_START) {
currentOnStart()
} else if (event == Lifecycle.Event.ON_STOP) {
currentOnStop()
}
}
// Add the observer to the lifecycle
lifecycleOwner.lifecycle.addObserver(observer)
// When the effect leaves the Composition, remove the observer
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
/* Home screen content */
}
Descripción completa de cómo funciona en el sitio de Google
https://developer.android.com/jetpack/compose/side-effects#disposableeffect
Abdelilah El Aissaoui
Edición 2: Hay un nueva edición tener esta función incluida en la API de Componer. Pensamiento aún no disponible (a partir de agosto de 2022)
Editar: Si desea una respuesta de redacción “pura”, consulte la respuesta de @JoJoIV
Respuesta:
Compose no es consciente de los cambios de estado como onPause
o onResume
debe manejarlo utilizando los métodos de la actividad principal.
Un ejemplo sería un LiveData
instancia en su actividad que se actualiza cada vez onResume
se ejecuta y obsérvelo como un estado en su componente principal principal.
Echemos un vistazo al siguiente ejemplo:
class MainActivity : AppCompatActivity() {
// Use whatever type your prefer/require, this is just an example
private val exampleLiveData = MutableLiveData("")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// Your main composable
MyApplicationTheme {
// Save the state into a variable otherwise it won't work
val state = exampleLiveData.observeAsState()
Log.d("EXAMPLE", "Recomposing screen - ${state.value}")
Surface(color = MaterialTheme.colors.background) {
Greeting("Android")
}
}
}
}
override fun onResume() {
super.onResume()
// Save whatever you want in your live data, this is just an example
exampleLiveData.value = DateTimeFormatter.ISO_INSTANT.format(Instant.now())
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
MyApplicationTheme {
Greeting("Android")
}
}
Como puede ver en este ejemplo, tengo un LiveData
propiedad en mi actividad que contiene una cadena. Cuando sea onResume
se ejecuta, la propiedad se actualiza con la nueva marca de tiempo y se recompone el componible de observación.
EunhaEonnie
Cambié @ojoIV código a esto (si su código componible está en Actividad)
@Composable
fun ComponentActivity.LifecycleEventListener(event: (Lifecycle.Event) -> Unit) {
val eventHandler by rememberUpdatedState(newValue = event)
val lifecycle = this@LifecycleEventListener.lifecycle
DisposableEffect(lifecycle) {
val observer = LifecycleEventObserver { _, event ->
eventHandler(event)
}
lifecycle.addObserver(observer)
onDispose {
lifecycle.removeObserver(observer)
}
}
}
uso
LifecycleEventListener(event = { lifecycleEvent ->
when (lifecycleEvent ) {
Lifecycle.Event.ON_CREATE -> {}
Lifecycle.Event.ON_START -> {}
Lifecycle.Event.ON_RESUME -> {}
Lifecycle.Event.ON_PAUSE -> {}
Lifecycle.Event.ON_STOP -> {}
Lifecycle.Event.ON_DESTROY -> {}
else -> return@LifecycleEventListener
}
})
-
Lindo ! Gracias ! pero el enlace de abajo está muerto.
– Mahdi Safarmohammadloo
5 de junio de 2022 a las 13:16
-
Lindo ! Gracias ! pero el enlace de abajo está muerto.
– Mahdi Safarmohammadloo
5 de junio de 2022 a las 13:16