-
-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
159 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Back button handling | ||
|
||
Some devices (e.g. Android) have hardware back buttons. A very common use case is to close the current screen, or the app if there is only one screen in the stack. Another possible use case is to show a confirmation dialog before closing the app. | ||
|
||
## Navigation with back button | ||
|
||
The `Router` can automatically navigate back when the back button is pressed. All you need to do is to supply the `handleBackButton=true` argument when you create the `Router`. Please see the related [documentation page](https://arkivanov.github.io/Decompose/router/overview/) for more information. | ||
|
||
## Manual back button handling | ||
|
||
The back button can be handled manually using `BackPressedDispatcher` (comes from [Essenty](https://github.com/arkivanov/Essenty) library), which is provided by `ComponentContext`. The `decompose` module adds Essenty's `back-pressed` module as `api` dependency, so you don't need to explicitly add it to your project. Please familiarise yourself with Essenty library, especially with the `BackPressedDispatcher`. | ||
|
||
### Usage example | ||
|
||
```kotlin | ||
import com.arkivanov.decompose.ComponentContext | ||
|
||
class SomeComponent( | ||
componentContext: ComponentContext | ||
) : ComponentContext by componentContext { | ||
|
||
init { | ||
backPressedDispatcher.register(::onBackPressed) | ||
} | ||
|
||
private fun onBackPressed(): Boolean { | ||
// Handle the back button. | ||
// Return true to consume the event, or false to allow other consumers. | ||
return false | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Instance retaining | ||
|
||
Sometimes it might be necessary to preserve state or data in a component when it gets destroyed. This commonly used in Android when configuration changes occur. The `ComponentContext` interface extends the `InstanceKeeperOwner` interface, which provides the `InstanceKeeper` - a multiplatform abstraction for instances retaining. It is provided by [Essenty](https://github.com/arkivanov/Essenty) library (from the same author). | ||
|
||
The `decompose` module adds Essenty's `instance-keeper` module as `api` dependency, so you don't need to explicitly add it to your project. Please familiarise yourself with Essenty library, especially with the `InstanceKeeper`. | ||
|
||
## Usage example | ||
|
||
```kotlin | ||
import com.arkivanov.decompose.ComponentContext | ||
import com.arkivanov.essenty.instancekeeper.InstanceKeeper | ||
import com.arkivanov.essenty.instancekeeper.getOrCreate | ||
|
||
class SomeComponent( | ||
componentContext: ComponentContext | ||
) : ComponentContext by componentContext { | ||
|
||
private val someLogic = instanceKeeper.getOrCreate(::SomeLogic) | ||
|
||
/* | ||
* Instances of this class will be retained. | ||
* ⚠️ Pay attention to not leak any dependencies. | ||
*/ | ||
private class SomeLogic : InstanceKeeper.Instance { | ||
override fun onDestroy() { | ||
// Clean-up | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,43 @@ | ||
# Lifecycle | ||
|
||
The component lifecycle is very similar to the [Android Activity lifecycle](https://developer.android.com/guide/components/activities/activity-lifecycle). There is the [Lifecycle](https://github.com/arkivanov/Decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/lifecycle/Lifecycle.kt) interface, each instance of the `ComponentContext` has its own instance of the `Lifecycle`. | ||
The component lifecycle is very similar to the [Android Activity lifecycle](https://developer.android.com/guide/components/activities/activity-lifecycle). The `ComponentContext` interface extends the `LifecycleOwner` interface, which provides the `Lifecycle` - a multiplatform abstraction for lifecycle states and events. It is provided by [Essenty](https://github.com/arkivanov/Essenty) library (from the same author). | ||
|
||
There is also [LifecycleRegistry](https://github.com/arkivanov/Decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/lifecycle/LifecycleRegistry.kt) which is the `Lifecycle` and the `Lifecycle.Callbacks` at the same time. `LifecycleRegistry` can be used to manually control the lifecycle. It can be passed to a root component, or can be used in tests. | ||
The `decompose` module adds Essenty's `lifecycle` module as `api` dependency, so you don't need to explicitly add it to your project. Please familiarise yourself with Essenty library, especially with the `Lifecycle`. | ||
|
||
Each component has its own lifecycle. The lifecycle of a child component can not be longer than its parent's lifecycle. | ||
|
||
<img src="https://raw.githubusercontent.com/arkivanov/Decompose/master/docs/media/LifecycleStates.png" width="512"> | ||
|
||
The lifecycle can be observed using its `subscribe`/`unsubscribe` methods: | ||
## Usage example | ||
|
||
```kotlin | ||
lifecycle.subscribe( | ||
object : DefaultLifecycleCallbacks { | ||
override fun onCreate() { | ||
// Handle lifecycle created | ||
} | ||
|
||
// onStart, onResume, onPause, onStop are also available | ||
|
||
override fun onDestroy() { | ||
// Handle lifecycle destroyed | ||
} | ||
import com.arkivanov.decompose.ComponentContext | ||
import com.arkivanov.essenty.lifecycle.Lifecycle | ||
import com.arkivanov.essenty.lifecycle.doOnCreate | ||
import com.arkivanov.essenty.lifecycle.subscribe | ||
|
||
class SomeComponent( | ||
componentContext: ComponentContext | ||
) : ComponentContext by componentContext { | ||
|
||
init { | ||
lifecycle.subscribe( | ||
object : Lifecycle.Callbacks { | ||
override fun onCreate() { | ||
/* Component created */ | ||
} | ||
|
||
// onStart, onResume, onPause, onStop, onDestroy | ||
} | ||
) | ||
|
||
lifecycle.subscribe( | ||
onCreate = { /* Component created */ }, | ||
// onStart, onResume, onPause, onStop, onDestroy | ||
) | ||
|
||
lifecycle.doOnCreate { /* Component created */ } | ||
// doOnStart, doOnResume, doOnPause, doOnStop, doOnDestroy | ||
} | ||
) | ||
``` | ||
|
||
Or using the extension functions: | ||
|
||
```kotlin | ||
lifecycle.subscribe( | ||
onCreate = { /* Handle lifecycle created */ }, | ||
// onStart, onResume, onPause, onStop are also available | ||
onDestroy = { /* Handle lifecycle destroyed */ } | ||
) | ||
|
||
lifecycle.doOnCreate { | ||
// Handle lifecycle created | ||
} | ||
|
||
// doOnStart, doOnResume, doOnPause, doOnStop are also available | ||
|
||
lifecycle.doOnDestroy { | ||
// Handle lifecycle destroyed | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# State preservation | ||
|
||
Sometimes it might be necessary to preserve state or data in a component when it gets destroyed. A very common use case is Android Activity recreation due to configuration changes, or process death. The `ComponentContext` interface extends the `StateKeeperOwner` interface, which provides the `StateKeeper` - a multiplatform abstraction for state preservation. It is provided by [Essenty](https://github.com/arkivanov/Essenty) library (from the same author). | ||
|
||
The `decompose` module adds Essenty's `state-keeper` module as `api` dependency, so you don't need to explicitly add it to your project. Please familiarise yourself with Essenty library, especially with the `StateKeeper`. | ||
|
||
## Usage example | ||
|
||
```kotlin | ||
import com.arkivanov.decompose.ComponentContext | ||
import com.arkivanov.essenty.parcelable.Parcelable | ||
import com.arkivanov.essenty.parcelable.Parcelize | ||
import com.arkivanov.essenty.statekeeper.consume | ||
|
||
class SomeComponent( | ||
componentContext: ComponentContext | ||
) : ComponentContext by componentContext { | ||
|
||
private var state: State = stateKeeper.consume(key = "SAVED_STATE") ?: State() | ||
|
||
init { | ||
stateKeeper.register(key = "SAVED_STATE") { state } | ||
} | ||
|
||
@Parcelize | ||
private class State(val someValue: Int = 0) : Parcelable | ||
} | ||
``` |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.