Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
Expand All @@ -52,6 +53,9 @@ import com.example.compose.snippets.interop.FirebaseAnalytics
import com.example.compose.snippets.interop.User
import com.example.compose.snippets.kotlin.Message
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch

Expand Down Expand Up @@ -263,3 +267,54 @@ fun DerivedStateOfWrongUsage() {
val fullNameCorrect = "$firstName $lastName" // This is correct
// [END android_compose_side_effects_derivedstateof_wrong]
}

@Composable
private fun SnapshotFlowExample() {
// [START android_compose_side_effects_snapshotflow]
val listState = rememberLazyListState()

LazyColumn(state = listState) {
// ...
}

LaunchedEffect(listState) {
snapshotFlow { listState.firstVisibleItemIndex }
.map { index -> index > 0 }
.distinctUntilChanged()
.filter { it == true }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For boolean flows, filter { it == true } can be simplified to filter { it } for better readability and conciseness. This is a common idiomatic expression in Kotlin.

Suggested change
.filter { it == true }
.filter { it }

.collect {
MyAnalyticsService.sendScrolledPastFirstItemEvent()
}
}
// [END android_compose_side_effects_snapshotflow]
}

private object MyAnalyticsService {
fun sendScrolledPastFirstItemEvent() {}
}

private object RestartingEffectsSnippet {
// [START android_compose_side_effects_restarting_effects]
@Composable
fun HomeScreen(
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
onStart: () -> Unit, // Send the 'started' analytics event
onStop: () -> Unit // Send the 'stopped' analytics event
) {
// These values never change in Composition
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This comment is misleading. The values held by currentOnStart and currentOnStop are updated on every recomposition, which is the purpose of rememberUpdatedState. The benefit is that using them inside an effect does not cause the effect to restart. A more accurate comment, like the one used in the other HomeScreen example in this file, would be clearer.

Suggested change
// These values never change in Composition
// Safely update the current lambdas when a new one is provided

val currentOnStart by rememberUpdatedState(onStart)
val currentOnStop by rememberUpdatedState(onStop)

DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
/* ... */
}

lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
// [END android_compose_side_effects_restarting_effects]
}
Loading