Одно-Одно Действие или Два Действия

#android #android-fragments #android-activity #navigation-drawer #android-navigation

Вопрос:

Основная часть моего приложения Activity (содержащая a NavigationDrawer ) позволяет перемещаться по многим (примерно 20) Fragment страницам из-за кликов по элементам NavDrawer и кликов других представлений внутри каждого фрагмента.

Затем он перемещается в точку, где мне нужен BottomNavigationView (сохраняя также навигатор). С этого момента из-за щелчков bottomNavView и других представлений я могу перейти к другим различным фрагментам, примерно 10-15, а также к тем, которые позволяет основной навигационный редактор, но в случае, если я перейду к Фрагменту с помощью щелчка по любому основному элементу NavDrawer, bottomNavView должен быть скрыт.

Итак, правильно ли здесь использовать подход с одним действием и контролировать видимость bottomNavView, или я должен использовать два действия, чтобы не зависеть от этого во всех навигациях?

Ответ №1:

Я не верю, что в этом случае есть «правильный или неправильный» ответ.

На самом деле все сводится к тому, как вы хотите спроектировать свое приложение, если вы последовательны.

Если у ваших фрагментов есть «состояние» и модель представления и тому подобное, то одно действие, обменивающееся фрагментами, контролируя свое собственное состояние (когда показывать нижнюю панель), может быть проще, чем поддерживать два разных действия, поскольку навигация всегда выполняется между фрагментами.

Это также будет связано с тем, как ведет себя backstack в каждом конкретном случае (поэтому протестируйте соответствующим образом, чтобы убедиться, что вы получите ожидаемое поведение).

Простая идея (одним действием)

Это псевдокод, не идеальный, компилируемый, функциональный код.

 class BottomBarUseCase() {
   operator fun invoke(destination: String): Boolean =
       when (destination) {
          "A", "B", "C" -> true
          else -> false
       }
}
 

Модель представления вашей деятельности (конечно, значительно упрощенная)

 class XXXViewModel(
   private val bottomBarUseCase: BottomBarUseCase
): ViewModel() {

    private val _state = MutableLiveData<YourState>(YourState.Empty)

    fun setupBottomBar(destination: String) {
       if (bottomBarUseCase(destination)) {
           _state.value = SomeState.ShowBar
       } else {
           _state.value = SomeState.HideBar
       }
    }
 

Ваша деятельность наблюдает за состоянием и делает то, что ему нужно делать.

Есть способы упростить это, а что нет, но, по сути, вы делегируете ответственность за отображение панели варианту использования, который вы можете протестировать изолированно, чтобы убедиться, что он делает то, что вы хотите (он же: не показывать панель для определенных мест назначения).

Вашим фрагментам все это безразлично (если только им тоже не нужно принимать решение, и в этом случае вы все равно можете ввести код использования в ViewModels Фрагмента и спросить там тоже, так как код использования не имеет никакой особой зависимости).

Это то, что я бы сделал, но без необходимости делать это в реальной жизни, трудно представить, будут ли у этого другие недостатки.

В общем, именно так я бы подошел к проблеме, которую необходимо решить во многих других местах: изолировать ее.

Надеюсь, это все прояснит.

Комментарии:

1. вы имеете в виду управление состоянием в каждом фрагменте или только в действии (оставаясь видимостью bottomnavview)

2. У меня был бы «Случай использования», который решает в зависимости от места назначения, показывать панель или нет. «Единое» действие вызовет пользователя/делегата для принятия решения и будет действовать соответствующим образом.

3. такс, и извините за поздний ответ. Проблема в том, что я не знаю, как уведомить действие о фрагменте, который отображается в данный момент, я имею в виду, что как только я перейду к Фрагменту, который обеспечит видимость панели, как уведомляется действие, кроме самого Фрагмента? кто вызывает setupBottomBar? Спасибо

4. Когда вы переходите к X, кто-то знает об этом. Это «состояние» — это то, с чем также будет консультироваться деятельность, когда придет время принимать решение. Кто-то (не деятельность, не фрагменты) должен знать (и хранить) эти знания. Когда вы нажмете на пункт назначения X, действие получит событие, которое поможет ему (или напрямую сообщит ему) решить, что делать с панелью. Ваш вопрос в том, как вызванный useCase знает, какой пункт назначения нужно пройти. Ну, вы могли бы (в модели просмотра активности?) следите за этим. Помните, что вы пересылаете события в модель представления и получаете события обратно…