Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rjrjr/compose-backstack
Simple composable for rendering transitions between backstacks.
https://github.com/rjrjr/compose-backstack
android compose jetpack-compose kotlin
Last synced: 3 days ago
JSON representation
Simple composable for rendering transitions between backstacks.
- Host: GitHub
- URL: https://github.com/rjrjr/compose-backstack
- Owner: rjrjr
- License: other
- Created: 2020-03-23T05:40:04.000Z (almost 5 years ago)
- Default Branch: main
- Last Pushed: 2023-02-20T21:15:17.000Z (almost 2 years ago)
- Last Synced: 2024-12-15T11:44:05.509Z (11 days ago)
- Topics: android, compose, jetpack-compose, kotlin
- Language: Kotlin
- Homepage:
- Size: 3.75 MB
- Stars: 506
- Watchers: 12
- Forks: 23
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# compose-backstack
[![Maven Central](https://img.shields.io/maven-central/v/com.zachklipp/compose-backstack.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.zachklipp%20a:compose-backstack)
[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)Simple library for [Jetpack Compose](https://developer.android.com/jetpack/compose) for rendering
backstacks of screens and animated transitions when the stack changes. It is _not_ a navigation
library, although it is meant to be easy to plug into your navigation library of choice
(e.g. [compose-router](https://github.com/zsoltk/compose-router)), or even just use on its own.The Compose version that this library is compatible with is indicated in this library's version
number.## Usage
The entry point to the library is the `Backstack` composable. It essentially looks like this:
```kotlin
@Composable fun Backstack(
backstack: List,
content: @Composable() (T) -> Unit
)
```The API is very similar to a lot of composables that draw lists: it takes a list of keys and a
composable function that knows how to draw a key. In this case, a key represents a distinct screen
in the backstack. When the top key in the stack changes between compose passes, the screens will
be animated with a transition.The actual API takes a few more parameters, e.g. to allow custom animations. See the
[source kdoc](compose-backstack/src/main/java/com/zachklipp/compose/backstack/Backstack.kt) for
details!## Example
```kotlin
sealed class Screen {
object ContactList: Screen()
data class ContactDetails(val id: String): Screen()
data class EditContact(val id: String): Screen()
}data class Navigator(
val push: (Screen) -> Unit,
val pop: () -> Unit
)@Composable fun App() {
var backstack: List by remember { mutableStateOf(listOf(Screen.ContactList)) }
val navigator = remember {
Navigator(
push = { backstack += it },
pop = { backstack = backstack.dropLast(1) }
)
}Backstack(backstack) { screen ->
when(screen) {
Screen.ContactList -> ShowContactList(navigator)
is Screen.ContactDetails -> ShowContact(screen.id, navigator)
is Screen.EditContact -> ShowEditContact(screen.id, navigator)
}
}
}
```## Custom transitions
Transitions between screens are defined by implementing the `BackstackTransition` interface and
passing the implementation to the `Backstack` composable. This interface has a single method:```kotlin
fun Modifier.modifierForScreen(
visibility: State,
isTop: Boolean
): Modifier
```The `modifierForScreen` method is called for every active/visible screen in the backstack, and must return a [`Modifier`](https://developer.android.com/reference/kotlin/androidx/ui/core/Modifier)
that will be applied to the entire screen. Compose has many `Modifier`s built-in, which can be used
to do a wide variety of visual transformations such as adjust position, size, transparency, etc.When animating between two screens, `visibility` will be somewhere
between 0 and 1 for both the top screen and the screen immediately under the top one.The `isTop` flag indicates if the returned modifier will be applied to the top screen or not, and
can be used to display a different animation for the top vs under-top screens. For example, the
`Slide` transition uses `isTop` to determine whether to translate the screen to the end/right, or
the start/left.Visibility will always transition between 0 and 1. If you need to map that range to a different
range of floats, or any other type, you can use one of the `lerp` functions provided by Compose.### Testing custom transitions
You can use the `BackstackViewerApp` composable in the `backstack-viewer` artifact to test your
custom transitions interactively. This composable is used by the sample app, and in the screenshots
below.## Inspecting the backstack
The `compose-backstack-xray` gives you a single extension function: `FrameController.xrayed(Boolean)`. This function returns a `FrameController` that will wrap its receiver and, when passed `true`, display it in an interactive, translucent, pseudo-3D stack – similar to Android Studio's Layout Inspector.
The top-most screen in the stack will still
be rendered in its regular position, but with a very low opacity, and will still be interactive.![Backstack inspector](.images/inspector.gif)
## Advanced usage: `FrameController`
Both transition animations and the xray tool are implemented via the `FrameController` API. This is the lowest-level way to plug into the `Backstack` function. More advanced features (e.g. stack peeking like the iOS back gesture) can be implemented by writing custom `FrameController`s. For more information, see the kdoc in the source: [`FrameController.kt`](compose-backstack/src/main/java/com/zachklipp/compose/backstack/FrameController.kt).
## Samples
There is a sample app in the `sample` module that demonstrates various transition animations and
the behavior with different backstacks.![Slide Transition](.images/sample-slide.gif)
![Crossfade Transition](.images/sample-crossfade.gif)
![Custom Transition](.images/sample-custom.gif)## Gradle
`compose-backstack` is on Maven Central:
```
allprojects {
repositories {
mavenCentral()
}
}dependencies {
implementation "com.zachklipp:compose-backstack:${Versions.backstack}"// For BackstackViewerApp.
debugImplementation "com.zachklipp:compose-backstack-viewer:${Versions.backstack}"
}
```