Comments 7
На мой взгляд, у вас все еще сильная связь между разными экранами, условно Product знает о существовании Home.
Я бы смотрел в сторону path-navigation. Благодаря нормальному DI и AOP в котлине, вы могли бы сделать что-то такое, только гораздо чище с точки зрения архитектуры.
Сейчас у вас больше config-based-router
Nav3Host(
backStack = backStack,
router = router,
) { backStack, onBack, _ ->
NavDisplay(
backStack = backStack,
onBack = onBack,
entryProvider = entryProvider {
entry<Screen.Home> { HomeScreen() } // !
entry<Screen.Details> { DetailsScreen() } // !
}
)
}
1) в чем по-вашему выражается сильная связь?
2) чем может помочь path навигация? если это выглядит так, как в примере ниже, то в android от этого очень долго пытались уйти в навигации от гугл и наконец ушли тк типизированная в контексте android подходит гораздо больше
entry("/path/to/screen")
3) чем плох config based router в контексте android разработки?
1) в чем по-вашему выражается сильная связь?
Вы пишите:
...передавать
NavBackStack
в ViewModel (что в моем понимании нарушает принципы архитектуры, так как я считаю...
То есть, ссылаетесь на какие-то принципы, но прямо не озвучиваете их. Напишите о каких принципах речь, и первый ваш вопрос отпадет.
2) чем может помочь path навигация? ...
...типизированная в контексте android подходит гораздо больше..
Типизированная в любом контексте лучше, я с этом полностью согласен. Но path-based тоже может быть типизированным.
3) чем плох config based router в контексте android разработки?
А как контекст андроид приложения меняет суть? Плох тем, что получается good-object + service-locator в одном.
Я честно не вижу, каким образом ваш роутер решил вами же описанные проблемы.
Было:
// Добавить экран
backStack.add(Screen.Details("123"))
// Вернуться назад
backStack.removeLastOrNull()
// Заменить текущий экран
backStack.set(backStack.lastIndex, Screen.Success)
стало
// Переход на новый экран
router.push(Screen.Details("123"))
// Возврат назад
router.pop()
// Переход с заменой текущего экрана (назад вернуться нельзя)
router.replaceCurrent(Screen.Success)
Чичероне для Nav3? Круто 👍
Проблемы начинаются, когда вам нужно вызвать навигацию из ViewModel. Придётся либо передавать NavBackStack в ViewModel (что в моем понимании нарушает принципы архитектуры, так как я считаю, что ViewModel не должна знать о Compose-специфичных вещах), либо создавать промежуточные callback'и для каждого действия навигации.
Вот как объявлен NavBackStack
:
class NavBackStack<T : NavKey> : MutableList<T>, StateObject
Что мешает передать его как MutableList
во вью-модель?
Что мешает передать его как
MutableList
во вью-модель?
Ничего не мешает, с этим просто неудобно работать
необходимо создать список, прокинуть его в compose и di
все еще нужно напрямую изменять список, что я лично для меня не является удобным
навигация доступна не из одного места в приложении, а во многих, другими словами, требуется протаскивать список по многим местам
Лично для меня это вопрос удобства и снижения количества возможных ошибок и проблем
Делаем Jetpack Navigation 3 удобнее