I'm working on a routing/navigation library for Je...
# compose
i
I'm working on a routing/navigation library for Jetpack compose (with a particular focus on being capable of supporting multiple modules). I'd like to hear about people's navigation requirements (beyond forward/back/modal presentation), such as a screen presenting another screen within itself, master/detail screens for tablets or larger devices. I would also like to hear suggestions on the API for the library - I've posted a small example of how I think it might work in the thread below.
Copy code
class HelloWorldRoute(...) 
  : Route

class HelloWorldViewModel :
  ViewModel<HelloWorldRoute>() { ... }

@Composable
fun HelloWorldScreen(
    viewModel: HelloWorldViewModel
) { ... }

val helloWorldRouter = router(
   HelloWorldViewModel::class
) {
    withView(::HelloWorldScreen)
    ... 
}


MyActivity.routerController = RouterController(
   helloWorldRouter,
   ...
)

MyActivity.onCreate() {
   ...
   routerController.open(HelloWorldRoute(...))
   setContent { 
      MaterialTheme { 
          RouterControllerContainer(
             routerController
          ) 
      } 
   }
}
m
Hi Isaac, As for me, the most annoying thing in jetpack’s navigation is bottom bar navigation with multiple backstacks support. Do you have any ideas regarding this?
i
Hi Max, I don't have any ideas yet, but I'm really interested to know what you find tricky about it! I assume you want to handle each tab as a different backstack? So when you've got a tab selected, only that tab will go back?
m
Yeap, as far as I remember, according to material guidelines, each tab might have its own backstack. Currently nav component doesn’t have support for multiple backstacks, an issue regarding this can be found here https://issuetracker.google.com/issues/80029773
i
Ok, thanks! That should be pretty easy to support 🙂
m
Is HelloWorldViewModel used as screen identifier for router here?
Copy code
val helloWorldRouter = router(
   HelloWorldViewModel::class
) {
    withView(::HelloWorldScreen)
    ... 
}
The reason why I’m asking because this is that for my pet project the navigation below was sufficient
Copy code
class AppState(
    val screens: Stack<Screen>
)

inline fun <reified T : Screen> State.updateScreen(
    id: ScreenId,
    how: (T) -> T
): State = ...

fun State.swapScreens(
    i: Int,
    j: Int = screens.lastIndex
)State {
...
}

fun State.pushScreen(
    screen: Screen
)State = ...

fun State.popScreen(): State = ...

private fun Activity.render(screen: Screen, onMessage: (Message) -> Unit) =
    setContent {
        App(screen, onMessage) {
            Screen(screen, onMessage)
        }
    }
i
I'm not quite sure what you mean by "screen identifier" - screen is unique based on instantiation. For example -
Copy code
val a = root.open(HelloWorldRoute("1"))
val b = a.open(HelloWorldRoute("2"))
"a" and "b" would be unique, and in this case, we would render the screen for HelloWorldRoute("2") and when we go back from that screen, we'd be back at the screen for HelloWorldRoute("1"). Even if HelloWorldRoute was an object, we would still end up with two unique screens.