-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResult.kt
More file actions
53 lines (48 loc) · 1.92 KB
/
Result.kt
File metadata and controls
53 lines (48 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package dev.vadzimv.jetpack.navigation.example.navigation
import android.os.Parcelable
import androidx.annotation.IdRes
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
fun <T : Parcelable> NavController.handleResult(
lifecycleOwner: LifecycleOwner,
@IdRes currentDestinationId: Int,
@IdRes childDestinationId: Int,
handler: (T) -> Unit
) {
// `getCurrentBackStackEntry` doesn't work in case of recovery from the process death when dialog is opened.
val currentEntry = getBackStackEntry(currentDestinationId)
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
handleResultFromChild(childDestinationId, currentEntry, handler)
}
}
currentEntry.lifecycle.addObserver(observer)
lifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
currentEntry.lifecycle.removeObserver(observer)
}
})
}
private fun <T : Parcelable> handleResultFromChild(
@IdRes childDestinationId: Int,
currentEntry: NavBackStackEntry,
handler: (T) -> Unit
) {
val expectedResultKey = resultName(childDestinationId)
if (currentEntry.savedStateHandle.contains(expectedResultKey)) {
val result = currentEntry.savedStateHandle.get<T>(expectedResultKey)
handler(result!!)
currentEntry.savedStateHandle.remove<T>(expectedResultKey)
}
}
fun <T : Parcelable> NavController.finishWithResult(result: T) {
val currentDestinationId = currentDestination?.id
if (currentDestinationId != null) {
previousBackStackEntry?.savedStateHandle?.set(resultName(currentDestinationId), result)
}
popBackStack()
}
private fun resultName(resultSourceId: Int) = "result-$resultSourceId"