代码之家  ›  专栏  ›  技术社区  ›  me.at.coding

从ViewModel了解导航命令模式

  •  0
  • me.at.coding  · 技术社区  · 4 年前

    Using Navigation Architecture Component in a large banking app

    在剖面图中 如何从ViewModels导航? 然而,有一件事我不明白。命令定义如下:

    sealed class NavigationCommand {
      data class To(val directions: NavDirections): NavigationCommand()
      object Back: NavigationCommand()
      data class BackTo(val destinationId: Int): NavigationCommand()
      object ToRoot: NavigationCommand()
    }
    

    我不明白的是,这里面 NavigationCommand 它实际上使用 导航命令 就像在 data class To(val directions: NavDirections): NavigationCommand() 再说一次-这不是以无限递归结束吗?另外,使用 object 就像在 object Back: NavigationCommand() ?

    0 回复  |  直到 4 年前
        1
  •  0
  •   Ivan Wooll    4 年前

    它实际上使用NavigationCommand

    这是Kotlin机制的扩展,该类在 : sealed -使类可枚举的一种方法 sealed classes

    你可以阅读有关对象的信息 here NavigationCommand

        2
  •  0
  •   Gurgen Gevondov    4 年前

    代码是用Kotlin语言编写的。它使用 sealed 类来定义所有命令。了解更多 密封的 类使用此 link

    1. 它所做的就是定义类 NavigationCommand 然后定义内部类 To . 打电话 NavigationCommand() 在定义过程中 类与调用超级构造函数相同。例如,对于 Java中的类可以这样编写:
    public class NavigationCommand {
    
        public static class To extends NavigationCommand {
    
            private NavDirections directions;
    
            public To(NavDirections directions) {
                super(); // This is the same as calling "NavigationCommand()" in To class definition
                this.directions = directions;
            }
    
        }
    
    }
    
    1. object 对象 关键字使用此 link
        3
  •  0
  •   quangson91    4 年前

    据我所知:

    sealed class NavigationCommand {
      data class To(val directions: NavDirections): NavigationCommand()
      object Back: NavigationCommand()
      data class BackTo(val destinationId: Int): NavigationCommand()
      object ToRoot: NavigationCommand()
    }
    

    actions 在一种情况下你能做到。 例如,图形中有一些片段: S -> A -> B -> C -> D .

    C .

    1. 我要导航到D->sendCommand: NavigationCommand.To(R.id.Id_Of_D)
    2. 我要导航到上一个屏幕:->sendCommand: NavigationCommand.Back
    3. 我想回到 A NavigationCommand.BackTo(R.id.Id_Of_A)
    4. 我要导航回当前图形的根目录:->sendCommand: NavigationCommand.ToRoot)

    您需要从视图模型发送一些命令,之后视图模型将向实时数据触发该事件。 接下来,这里最重要的- How is that event is comsumed 你得看一下 BaseFragment

    override fun onActivityCreated(savedInstanceState: Bundle?) {
      super.onActivityCreated(savedInstanceState)
      vm?.navigationCommands?.observe { command ->
        when (command) {
          is NavigationCommand.To ->      
            findNavController().navigate(command.directions)
            …
    

    BaseFragment.kt

    open class BaseFragment : Fragment() {
        open val baseViewModel: BaseViewModel? = null
    
        override fun onActivityCreated(savedInstanceState: Bundle?) {
            super.onActivityCreated(savedInstanceState)
            baseViewModel?.navigationCommands?.observeEventNonNull(viewLifecycleOwner) { command ->
                val navController = findNavController()
                when (command) {
                    is NavigationCommand.To -> navController.navigate(command.directions)
                    NavigationCommand.Back -> navController.popBackStack()
                    is NavigationCommand.BackTo ->
                        navController.popBackStack(command.destinationId, false)
                    NavigationCommand.ToRoot ->
                        navController.popBackStack(navController.graph.startDestination, false)
                }
            }
        }
    }
    

    因此,到目前为止,您将看到,我们在视图模型中发布的所有事件 navigationCommands

    推荐文章