Почему навигация запускается из фрагментов? - PullRequest
0 голосов
/ 11 октября 2019

Я пытаюсь настроить свой проект в соответствии с шаблоном MVVM и использую компоненты архитектуры Android от Jetpack.

У меня есть фрагмент-заставка, во время которого выполняется HTTP-запрос и в зависимости от негов ответе пользователь будет перемещен либо к представлению настроек, либо к основному представлению.

FragmentSplash:

class FragmentSplash : Fragment()
{
    private lateinit var viewModelSplash: ViewModelSplash

    override fun onCreateView( inflater: LayoutInflater,
                               container: ViewGroup?,
                               savedInstanceState: Bundle? ): View?
    {
        viewModelSplash = ViewModelProviders.of( this ).get( ViewModelSplash::class.java )
        return inflater.inflate(com.host.myproject.R.layout.fragment_splash, container, false )
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?)
    {
        viewModelSplash.command.observe(this, Observer {
            when( it ) // I know strings are bad :)
            {
                "NAVIGATE_TO_MAIN" -> Navigation.findNavController( view ).navigate( R.id.action_showConfirm )
                "NAVIGATE_TO_"     -> Navigation.findNavController( view ).navigate( R.id.action_showBase )
            }
        });

        super.onViewCreated(view, savedInstanceState)
    }
}

ViewModelSplash:

class ViewModelSplash : ViewModel()
{
    private val _command = MutableLiveData<String>()
    val command: LiveData<String>
        get() = _command

    init
    {
        Timer("fakeHTTPRequest", false).schedule(3500) {
            onInitializationFinished( response )
        }
    }

    private fun onInitializationFinished( response : Response )
    {
        if( response.ok )
            _command.postValue( "NAVIGATE_TO_MAIN" )
        else
            _command.postValue( "NAVIGATE_TO_CONFIRM" )
    }
}

Проблемая вижу вот что:

-The FragmentSplash contains logic pattern the "when" statement
-The FragmentSplash is aware of other fragments

Я пытаюсь понять, как правильно реализовать это, так как все примеры, которые я видел до сих пор, вызывают навигатор внутри фрагмента после того, как ViewModel изменяетданные внутри наблюдаемого:

viewModelSplash.command.observe(this, Observer {
...
    Navigation.findNavController( view ).navigate
...

Я полностью потерян .. Разве это не противоречит "1017 *

" "независимость взглядов / логики"?

Я бы подумал, что должен быть какой-то класс Router, который получает уведомление от ViewModel о том, что ему нужно перемещаться в другое место, чтобы представление было полностью чистым. Любые предложения, куда идти отсюда, пожалуйста?

1 Ответ

0 голосов
/ 22 октября 2019

Вы можете попытаться использовать команды навигации в реальном времени для данных в модели представления и наблюдать их в BaseFragment. Допустим, вы хотите перейти от фрагмента A к фрагменту B, а затем:

Команды навигации

sealed class NavigationCommand {
  data class navigateTo(val directions: NavDirections): NavigationCommand()
  object Back: NavigationCommand()
}

В BaseFragment

viewModel.navigationCommands.observe { command ->
    when (command) {
      is NavigationCommand.navigateTo ->      
        findNavController().navigate(command.directions)
      NavigationCommand.Back ->      
        findNavController().popBackStack()
      }
    }

В ViewModel

fun navigate(directions: NavDirections) {
  navigationCommands.postValue(NavigationCommand.To(directions))
}

Навигация из ViewModel

navigate(FragmentADirections.actionToFragmentB())

Это только один подход, и вы можете проверить это Используя компонент архитектуры навигации в большом банковском приложении . У этого есть большое объяснение навигации от модели представления и удаления кода пластины котла из фрагмента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...