Simple composable for rendering transitions between backstacks.
Simple library for 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), or even just use on its own.
The Compose version that this library is compatible with is indicated in this library's version number.
The entry point to the library is the
Backstackcomposable. It essentially looks like this:
@Composable fun Backstack( backstack: List, drawScreen: @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 for details!
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 by state { 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) } } }
Transitions between screens are defined by implementing the
BackstackTransitioninterface and passing the implementation to the
Backstackcomposable. This interface has a single method:
fun modifierForScreen( visibility: Float, isTop: Boolean ): Modifier
The
modifierForScreenmethod is called for every screen in the backstack (even ones that are completely hidden), and must return a
Modifierthat will be applied to the entire screen. Compose has many
Modifiers built-in, which can be used to do a wide variety of visual transformations such as adjust position, size, transparency, etc.
When not currently transitioning,
visibilitywill be 0 for all screens except the top one, for which
visibilitywill be 1. When animating between two screens,
visibilitywill be somewhere between 0 and 1 for both the top screen and the screen immediately under the top one. The visibility of all other screens in the stack will continue to be 0.
The
isTopflag 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
Slidetransition uses
isTopto 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
lerpfunctions provided by Compose.
You can use the
BackstackViewerAppcomposable in the
backstack-viewerartifact to test your custom transitions interactively. This composable is used by the sample app, and in the screenshots below.
The
Backstackcomposable takes an optional
InspectionParamsparameter. When not null, the entire backstack will be rendered as a translucent 3D stack. 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. The
BackstackInspectorParamscontrols how the stack is rendered, including rotation, scaling, opacity, etc.
You can wrap your
Backstackwith the
InspectionGestureDetectorcomposable to automatically control the inspector mode using touch gestures.
There is a sample app in the
samplemodule that demonstrates various transition animations and the behavior with different backstacks.
compose-backstackis on Maven Central:
allprojects { repositories { mavenCentral() } }dependencies { implementation "com.zachklipp:compose-backstack:${Versions.backstack}"
// For BackstackViewerApp. debugImplementation "com.zachklipp:compose-backstack-viewer:${Versions.backstack}"
}