【问题标题】:Why is the navigation triggered from the Fragments?为什么从 Fragments 触发导航?
【发布时间】:2019-10-11 13:25:09
【问题描述】:

我正在尝试根据 MVVM 模式设置我的项目,并且我正在使用 Jetpack 的 Android 架构组件。

我有一个“splash”片段,在此期间发出 HTTP 请求,根据响应,用户将被导航到设置视图或主视图。

片段飞溅:

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 更改可观察对象中的数据后调用 Fragment 中的导航器:

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

我完全迷路了..不是这样

与“视图/逻辑的独立性”相矛盾?

我认为应该有某种路由器类,它从 ViewModel 获得通知,它需要在其他地方导航,这样视图就会完全干净。请问有什么建议可以从这里去吗?

【问题讨论】:

  • 您找到合适的解决方案了吗?我也想知道。
  • Same here...Android 架构组件范例似乎在架构方面做得并不好...

标签: android kotlin mvvm


【解决方案1】:

您可以尝试在视图模型中使用导航命令实时数据并在 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()
      }
    }

在视图模型中

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

从 ViewModel 导航

navigate(FragmentADirections.actionToFragmentB())

这只是一种方法,您可以查看Using Navigation Architecture Component in a large banking app。 它对从视图模型导航和从片段中删除样板代码有很好的解释。

【讨论】:

  • 似乎有点老套的解决方法。有没有更惯用的方法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多