Как в Android правильно организовать навигацию через MVVM?
Добрый день.
Начал изучать android-разработку и столкнулся с, казалось бы, простой, но, тем не менее, нигде толком не описанной задачей: организация навигации по приложению.
В чем проблема: в login_layout есть кнопка перехода к регистрации (registration_layout). Кнопка привязана к PublishSubject в LoginViewModel. PublishSubject был выбран потому, что через стандартную реализацию MutableLiveData происходит неприятный эффект: при повторном открытии LoginActivity срабатывает observe этой LiveData, что приводит к редиректу на страницу регистрации, что, в свою очередь, тригерит такой же observe, но уже на страницу логина - итого, бесконечный цикл. Решения этой проблемы не нашел: даже в книжках а-ля: "Андроид для сурьезных пацанов", приводят примеры каких-то левых приложений, типа BeatBox панели, в которой, очевидно, нет никакой навигации.
PublishSubject решил проблему бесконечного редиректа (ибо при подписке не эмитит последнее значение), но осталась еще одна проблема: непонятно как работающая кнопка "назад" (физическая BackButton).
Что я имею ввиду: вот есть две страницы - логин и регистрация. С них обеих можно переходить туда-сюда. По логике, в стеке истории должны храниться все переходы: логин - регистрация - логин - регистрация и т.д. И при нажатии на кнопку, должна открываться предыдущая страница. Но что происходит сейчас: переход рандомный - иногда он отрабатывает по порядку, но чаще - при нажатии открывается та же самая страница. Т.е. на регистрации нажимаю BackButton - открывается опять регистрация. Еще раз нажимаю - только тогда открывается логин. Нажимаю на логине BackButton - открывается опять логин. И так далее, в зависимости от количества переходов в цепочке.
Пробовал вызывать finish() после startActivity() - не помогло. Указывал noHistory="true" в манифесте - не помогло. Делал intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - без того же результата.
Знаю, что можно как-то организовать навигацию в специальном файле, но пока решил не трогать. Да и не думаю, что такой подход решит проблему с BackButton.
Где можно почитать хороший мануал по этой теме? Книги какие и т.д. В сети такую проблему не нашел.
А после выполнения перехода или до перехода livedata почему не сбрасывается? При переходе на логин она ведь не сразу true для перехода на регистрацию. Так почему при возврате она снова true?
zdezak, если ее не сбрасывать - значение остается, т.к. оно находится в классе. Соответственно, оно и вернется при повторной подписке. А надо ли его сбрасывать - это уже к экспертам. Я не в курсе.
MamaLuyba, по вопросу организации навигации в андроид лучше посмотреть вот этот курс от гугл. Как сделать через jetpack navigation, чтобы не было возврата на туже страницу описано здесь. Если кратко, то после совершения навигации значение MutableLiveData должно быть возвращено, чтобы при нажатии кнопки назад не происходил переход на регистрацию без нажатия на кнопку.
MamaLuyba, Советую ознакомится или лучше пройти курс (он бесплатный, есть субтитры, которые авто переводчиком можно перевести прямо на видео). Позволит понимать большинство тем в андроид разработке.
Библиотека не сложна в использовании и имеет достаточно примеров и документации. К тому же она простая - можно допилить под себя. Автор библиотеки весьма отзывчив и рассматривает любые предложения.