Jetpack compose - 当应用 returns 进入前台时如何刷新屏幕
Jetpack compose - how do I refresh a screen when app returns to foreground
当应用 returns 进入前台时,我需要自动刷新 Android 撰写屏幕。
我需要权限和定位服务。
如果用户关闭了其中的任何一项,则会列出需要更改的项目。当用户转到“设置”并将应用 returns 转到前台时,我希望列表能够刷新以反映更改。
我正在使用 Compose 和 Compose 导航。我已经看过,但无法找出可用于触发刷新的 onResume 生命周期事件的等价物。
任何想法都将不胜感激,因为我不知所措。
编辑: 如果您想要“纯”撰写答案,请选中
答案:
Compose 无法感知 onPause
或 onResume
等状态变化,您必须使用父 activity 的方法来处理它。
一个例子是 activity 中的一个 LiveData
实例,它会在每次执行 onResume
时更新,并将其作为主要父可组合项中的状态进行观察。
我们来看下面的例子:
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")
}
}
如您在此示例中所见,我的 activity 中有一个 LiveData
属性,其中包含一个字符串。每当执行 onResume
时,属性 都会更新为新的时间戳,并且会重新组合观察可组合项。
我想到了这个:
@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)
}
}
}
它似乎工作得很好。但在某些情况下可能会出现一些问题,请注意。
也有可能是有些冗余代码。
用法:
OnLifecycleEvent { owner, event ->
// do stuff on event
when (event) {
Lifecycle.Event.ON_RESUME -> { /* stuff */ }
else -> { /* other stuff */ }
}
}
我略微改进了 @JojoIV 的答案,并使其在没有回调的情况下使用平坦,就像您观察到 LiveData
在撰写 @Abdelilah El Aissaoui 回答了
@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
}
然后是用法
@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
}
示例来自 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 */
}
在 google 站点中对其工作原理的完整描述
https://developer.android.com/jetpack/compose/side-effects#disposableeffect
我把@ojoIV代码改成了这个
(如果您的可组合代码在 Activity 中)
@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)
}
}
}
用法
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
}
})
当应用 returns 进入前台时,我需要自动刷新 Android 撰写屏幕。
我需要权限和定位服务。
如果用户关闭了其中的任何一项,则会列出需要更改的项目。当用户转到“设置”并将应用 returns 转到前台时,我希望列表能够刷新以反映更改。
我正在使用 Compose 和 Compose 导航。我已经看过,但无法找出可用于触发刷新的 onResume 生命周期事件的等价物。
任何想法都将不胜感激,因为我不知所措。
编辑: 如果您想要“纯”撰写答案,请选中
答案:
Compose 无法感知 onPause
或 onResume
等状态变化,您必须使用父 activity 的方法来处理它。
一个例子是 activity 中的一个 LiveData
实例,它会在每次执行 onResume
时更新,并将其作为主要父可组合项中的状态进行观察。
我们来看下面的例子:
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")
}
}
如您在此示例中所见,我的 activity 中有一个 LiveData
属性,其中包含一个字符串。每当执行 onResume
时,属性 都会更新为新的时间戳,并且会重新组合观察可组合项。
我想到了这个:
@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)
}
}
}
它似乎工作得很好。但在某些情况下可能会出现一些问题,请注意。
也有可能是有些冗余代码。
用法:
OnLifecycleEvent { owner, event ->
// do stuff on event
when (event) {
Lifecycle.Event.ON_RESUME -> { /* stuff */ }
else -> { /* other stuff */ }
}
}
我略微改进了 @JojoIV 的答案,并使其在没有回调的情况下使用平坦,就像您观察到 LiveData
在撰写 @Abdelilah El Aissaoui 回答了
@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
}
然后是用法
@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
}
示例来自 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 */
}
在 google 站点中对其工作原理的完整描述 https://developer.android.com/jetpack/compose/side-effects#disposableeffect
我把@ojoIV代码改成了这个 (如果您的可组合代码在 Activity 中)
@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)
}
}
}
用法
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
}
})