zsoltk / compose-router Goto Github PK
View Code? Open in Web Editor NEW[DEPRECATED] Routing functionality for Jetpack Compose with back stack
License: Apache License 2.0
[DEPRECATED] Routing functionality for Jetpack Compose with back stack
License: Apache License 2.0
With deeplink I think it's support between Dynamice Feature navigation, cmiiw or does it requires any setup/configuration differences than using Deeplink?
Version of Jetpack Compose: alpha07
Version of Compose router: 0.21.0
The following runtime error is thrown
java.lang.NoSuchFieldError: No field Companion of type Landroidx/compose/runtime/SlotTable$Companion; in class Landroidx/compose/runtime/SlotTable; or its superclasses (declaration of 'androidx.compose.runtime.SlotTable' appears in /data/data/com.metamythlabs.theseries/code_cache/.overlay/base.apk/classes.dex)
at com.github.zsoltk.compose.router.RouterKt.Router(Router.kt:105)
at com.metamythlabs.theseries.screens.MainRouter$Companion.Content(MainRouter.kt:28)
Usage of router (excerpt)
companion object {
@Composable
fun Content(defaultRouting: Routing = Routing.Home) {
Router("Main", defaultRouting) { backStack ->
Providers(
AppNavigatorAmbient provides TheSeenNavigator(backStack)
) {
when (val routing = backStack.last()) {
is Routing.Home -> HomeRouter.Content()
is Routing.MoviesDetail -> MovieRouter.Content(movieId = routing.movieId)
is Routing.SeriesDetail -> SeriesRouter.Content(seriesId = routing.seriesId)
is Routing.UniverseDetail -> UniverseRouter.Content(universeId = routing.universeId)
}
}
}
}
}
}
Sadly I couldn't solve it quickly, hence I wanna report it.
Version 0.11.1 crashes withbackPressHandler is not initialized
at a certain route depth. Downgrading to 0.9.0 fixes the issue. I'm having trouble reproducing this properly.
Would be nice if you update your lib to version dev12.
Right now Router needs an explicit unique id for back stack store/retrieval from parent. It would be nice to make this implicitly without having to ask client code to define id.
Would be nice to also support kotlin multiplatform - i.e. kotlin native targets, js and non-android jvm.
The use of Router
in a jetpack compose project using version 0.1.0-dev08
will crash the application on startup.
The ViewModels provided in the composition by hilt, are never destroyed when a new root destination is selected.
With compose navigation this is different because models are cleared as soon as the destination gets cleared from the back stack.
I mentioned this bug in #21. Probably needs to be reported to Google. It still does not work with 4.1.0-alpha09.
For some reason with com.android.tools.build:gradle versions 4.1.0-alpha06 - 4.1.0-alpha08 the META-INF folder isn't added to the classes.jar in the .aar outputs
My branch built with com.android.tools.build:gradle:4.1.0-alpha05
includes the META-INF folder and I can successfully build my project
Assuming you have two destinations, A and B. A displays a long list. You click on an item in the list to navigate to B. Once in B you click on the back button. The A view is entirely recreated. The list is at the top again. I am unsure if this is by design or not.
sealed class Routing {
object A: Routing()
data class B(val slug: String) : Routing()
}
@Composable
fun AppStore(routing: Routing = Routing.A) {
Router(routing) { backStack ->
val onItemClicked: (String) = { slug ->
backStack.push(Routing.B(slug))
}
when (val value = backStack.last()) {
is Routing.A-> AController(onItemClicked)
is Routing.B-> BController(value.slug)
}
}
}
I've already added a rememberLazyListState
but this seems to be recreated entirely as well
I am using version 0.24.2
Hi,
I'd find it really useful to know what the top item in the backstack is - I'm using bottom navigation and knowing the top item on the backstack would help in deciding which item at the bottom should be highlighted (even when a few destinations deep in that stack).
Is there a reason this shouldn't be exposed?
I wonder if there is any way to retrieve all elements from BackStack
?
It can be useful in the following cases:
BackStack
on top of each other, so after navigating back we will not re-render some screens.Composable
. There are some workarounds, such as using Kotlin Reflection or using state/remember
for maintaining backstack yourself, but it would be great to have read access directly to BackStack#elements
.@zsoltk WDYT?
Initial setup of BackPressHandler in the MainActivity works well with navigation but how to handle Appbar navback button click event?
Now I've forked and created RootBackPressHandler Ambient which is set once in root Router and then I'm accessing it from anywhere
I'm trying out your library (0.5.0) and it's great. But I ran into an issue. I will post code here to reproduce it. I might be using the library wrong though.
class MainActivity : AppCompatActivity() {
private val backPressHandler = BackPressHandler()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Providers(AmbientBackPressHandler provides backPressHandler) {
MyRouter(startRoute = SplashRoute)
}
}
}
}
override fun onBackPressed() {
if (!backPressHandler.handle()) {
super.onBackPressed()
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.saveAmbient()
}
}
sealed class MyRoute {
object SplashRoute : MyRoute()
object HomeRoute : MyRoute()
object DetailsRoute : MyRoute()
}
@Composable
fun MyRouter(startRoute: MyRoute) {
Router(contextId = "app", defaultRouting = startRoute) { backStack ->
when (backStack.last()) {
SplashRoute -> SplashRouteScreen(onInitialized = { backStack.newRoot(HomeRoute) })
HomeRoute -> HomeRouteScreen(onShowDetails = { backStack.push(DetailsRoute) })
DetailsRoute -> DetailsRouteScreen()
}
}
}
@Composable
fun SplashRouteScreen(onInitialized: () -> Unit) {
onActive {
onInitialized()
}
}
@Composable
fun HomeRouteScreen(onShowDetails: () -> Unit) {
onActive {
Log.d("HomeRouteScreen", "onActive ${System.currentTimeMillis()}")
onDispose {
Log.d("HomeRouteScreen", "onDispose ${System.currentTimeMillis()}")
}
}
Center {
Button(onClick = onShowDetails) {
Text(text = "Show details")
}
}
}
@Composable
fun DetailsRouteScreen() {
Center {
Text("Details")
}
}
So if you open the app and you navigate through screens everything is fine. Logs in HomeRouteScreen
work as intended. But if you leave the app with back button (don't kill the app), then:
Logs will look like this:
D/HomeRouteScreen: onActive 1582533598703
D/HomeRouteScreen: onDispose 1582533600692
D/HomeRouteScreen: onDispose 1582533600697
D/HomeRouteScreen: onActive 1582533602550
D/HomeRouteScreen: onActive 1582533602551
If you leave the app again, and repeat those steps:
HomeRouteScreen: onActive 1582533684493
HomeRouteScreen: onDispose 1582533699006
HomeRouteScreen: onDispose 1582533699009
HomeRouteScreen: onDispose 1582533699011
HomeRouteScreen: onActive 1582533699988
HomeRouteScreen: onActive 1582533699989
HomeRouteScreen: onActive 1582533699989
Seems like every time you close the app with back button then reopen, something gets duplicated.
It would be nice to have one. ;)
compose-router does not specify an open source license. This implies, as it is generally understood, that it cannot be assumed to be open source.
@zsoltk could you please clarify this matter and, if compose-router is indeed meant to be open-source, could you add a license file?
My understanding of the replace
function on BackStack
is that it should swap the item at the top of the stack, so if the routing is a,b,c
and replace(d)
is called it should become a,b,d
.
However, the replace function uses .subList(0, elements.lastIndex - 1)
which removes 2 elements (the second argument being exclusive).
This should probably either change to use size
or remove the -1
(the latter makes more sense to me).
This is, of course, all invalid if I've misunderstood what replace is supposed to do.
what is .LifelikeActivity?
maybe delete?
Goal
To not block updating the library itself by breaking example apps UI whenever a new compose version is available.
How
Make the example apps grab the built artifact from jitpack instead of compiling from inside the project.
It's understood that this implies that example apps can and will become outdated UI-wise. Their point is to demonstrate Router usage though, and that remains very much the same across Compose versions.
The benefit of being able to update library itself very quickly is worth this trade-off.
What should happen: Back stack should be popped alternatively between L4.R1 and L4.R2
What happens: First L4.R1 gets fully popped, then L4.R2
I created another repository with navigation library where I solved this by having a "Global stack" that handles back stacks from each Router.
I'm wondering if it's possible to adapt compose-router to be able to scope AndroidX ViewModel to a Backstack
element?
For example, as long as the route is still in the backstack then the ViewModel is kept alive, and once the route is popped ViewModel's onCleared()
gets called.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.