Wil*_*iam 4 android android-lifecycle android-jetpack-compose
当应用程序返回到前台时,我需要自动刷新 Android Compose 屏幕。
我有一个需要权限和位置服务的。
如果用户关闭了其中的任何一个,则会绘制一个包含需要更改的项目的列表。当用户转到“设置”并且应用程序返回到前台时,我希望刷新列表以反映更改。
我正在使用 Compose 和 Compose 导航。我已经看过了,但无法弄清楚可用于触发刷新的 onResume 生命周期事件的等效项。
任何想法将不胜感激,因为我不知所措。
Ars*_*ius 52
我稍微改进了@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
}
Run Code Online (Sandbox Code Playgroud)
然后使用
@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
}
Run Code Online (Sandbox Code Playgroud)
Abd*_*oui 47
使用官方 API(需要 Lifecycle Runtime Compose 2.7.0):
\nimplementation("androidx.lifecycle:lifecycle-runtime-compose:2.7.0")\nRun Code Online (Sandbox Code Playgroud)\n检测更改的官方方法Lifecycle.State是使用以下代码片段:
val lifecycleOwner = LocalLifecycleOwner.current\nval lifecycleState by lifecycleOwner.lifecycle.currentStateFlow.collectAsState()\n\nLaunchedEffect(lifecycleState) {\n // Do something with your state\n // You may want to use DisposableEffect or other alternatives\n // instead of LaunchedEffect\n when (lifecycleState) {\n Lifecycle.State.DESTROYED -> {}\n Lifecycle.State.INITIALIZED -> {}\n Lifecycle.State.CREATED -> {}\n Lifecycle.State.STARTED -> {}\n Lifecycle.State.RESUMED -> {}\n }\n}\nRun Code Online (Sandbox Code Playgroud)\ncollectStateAsState是一个方便的扩展函数,它通过使用 Lifecycle 的新属性来收集 State 更改currentStateFlow。所以上面的代码与执行相同:
val lifecycleOwner = LocalLifecycleOwner.current\nval state by lifecycleOwner.lifecycle.currentStateFlow.collectAsState()\n\nLaunchedEffect(state) {\n // Do something with your state\n // You may want to use DisposableEffect or other alternatives \n // instead of LaunchedEffect\n}\nRun Code Online (Sandbox Code Playgroud)\n请记住导入androidx.compose.runtime.getValue以直接访问Lifecycle.State.
正如 @H\xc3\xa5konSchia 所提到的,您还可以使用 DiposableEffect 的变体,这些变体也考虑了生命周期:
\nLifecycleStartEffect(Unit) {\n // Do something on start or launch effect\n\n onStopOrDispose {\n // Do something on stop or dispose effect\n }\n}\n\nLifecycleResumeEffect(Unit) {\n // Do something on resume or launch effect\n\n onPauseOrDispose {\n // Do something on pause or dispose effect\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n旧答案:
\nCompose 不知道状态更改,例如onPause或onResume,您必须使用父活动的方法来处理它。
一个示例是LiveData您的活动中的一个实例,每次onResume执行时都会更新,并将其作为主要父可组合项中的状态进行观察。
让我们看一下下面的例子:
\nclass MainActivity : AppCompatActivity() {\n // Use whatever type your prefer/require, this is just an example\n private val exampleLiveData = MutableLiveData("")\n\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n setContent {\n // Your main composable\n MyApplicationTheme {\n // Save the state into a variable otherwise it won\'t work\n val state = exampleLiveData.observeAsState()\n Log.d("EXAMPLE", "Recomposing screen - ${state.value}")\n\n Surface(color = MaterialTheme.colors.background) {\n Greeting("Android")\n }\n }\n }\n }\n\n override fun onResume() {\n super.onResume()\n\n // Save whatever you want in your live data, this is just an example\n exampleLiveData.value = DateTimeFormatter.ISO_INSTANT.format(Instant.now())\n }\n}\n\n@Composable\nfun Greeting(name: String) {\n Text(text = "Hello $name!")\n}\n\n@Preview(showBackground = true)\n@Composable\nfun DefaultPreview() {\n MyApplicationTheme {\n Greeting("Android")\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n正如您在此示例中看到的,LiveData我的活动中有一个包含字符串的属性。每当onResume执行时,属性都会使用新的时间戳进行更新,并且观察可组合项会被重构。
Эва*_*ist 27
来自谷歌网站的示例
@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 */
}
Run Code Online (Sandbox Code Playgroud)
谷歌网站上对其工作原理的完整描述 https://developer.android.com/jetpack/compose/side-effects#disposableeffect
我也需要这个,但什么也没找到。然后我想出了这个:
@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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
它似乎工作得很好。但在某些情况下可能会出现一些问题,所以要小心。
也有可能存在一些冗余代码。
创建效用函数:
@Composable
fun rememberLifecycleEvent(lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current): Lifecycle.Event {
var state by remember { mutableStateOf(Lifecycle.Event.ON_ANY) }
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
state = event
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
return state
}
Run Code Online (Sandbox Code Playgroud)
在您的屏幕可组合项中使用它:
val lifecycleEvent = rememberLifecycleEvent()
LaunchedEffect(lifecycleEvent) {
if (lifecycleEvent == Lifecycle.Event.ON_RESUME) {
// initiate data reloading
}
}
Run Code Online (Sandbox Code Playgroud)
来源:Jetpack Compose 与生命周期感知可组合项
| 归档时间: |
|
| 查看次数: |
1822 次 |
| 最近记录: |