https://kotlinlang.org logo
#compose
Title
# compose
i

Isaac Udy

12/11/2019, 11:27 PM
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

Max Oliynick

12/12/2019, 9:28 AM
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

Isaac Udy

12/12/2019, 10:22 AM
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

Max Oliynick

12/12/2019, 11:27 AM
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

Isaac Udy

12/12/2019, 11:32 AM
Ok, thanks! That should be pretty easy to support 🙂
m

Max Oliynick

12/12/2019, 11:34 AM
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

Isaac Udy

12/12/2019, 9:44 PM
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.