虽然JetPack的导航组件看起来非常有前景,但我找到了一个无法找到实现我想要的方法的地方 .

我们来看一个示例应用程序屏幕:

该应用程序有一个主要活动,一个顶部工具栏,一个底部工具栏与fab连接 . 我面临着两个挑战,我想让它们成为正确的方法 .

1. I need to implement fragment transactions in order to allow replacing the fragment on the screen, based on the user interaction. 我可以通过三种方式思考并实施此方法:

  • 回调的方式 . 在片段中有一个接口 onFragmentAction 回调并且有活动实现它 . 所以基本上当用户按下 FragmentA 中的按钮时,我可以用params调用 onFragmentAction ,这样活动就会触发并启动例如事务用 FragmentB 替换它

  • 从JetPack实现 Navigation 组件 . 虽然我已经尝试过并且看起来非常简单,但由于无法检索当前片段而遇到了问题 .

  • 在片段和活动之间使用共享 ViewModel ,从片段更新它并在活动中观察它 . 这将是"replacement"的回调

2. Since the FAB is in the parent activity, when pressed, I need to be able to interact with the current visible fragment and do an action. For instance, add a new item in a recyclerview inside the fragment. So basically a way to communicate between the activity and fragment 我可以通过两种方式思考如何做到这一点

  • 如果不使用 Navigation 那么我可以使用 findFragmentById 并检索当前片段并运行公共方法来触发操作 .

  • 在片段和活动之间使用共享'ViewMode',从活动更新它并在片段中观察它 .

所以,正如你所看到的,推荐的导航方法是使用新的'Navigation'架构组件,但是,目前它缺乏检索当前片段实例的方法,因此我不知道如何在活动之间进行通信和片段 . 这可以通过 shared ViewModel 实现,但在这里我有一个缺失的部分:我理解片段到片段的通信可以使用共享的ViewModel . 我认为当片段有一些共同点时,这是有道理的,就像Master / Detail情节一样,共享相同的viewmodel非常有用 .

但是,然后在活动和 ALL 片段之间进行讨论,如何使用共享 ViewModel ?每个片段都需要自己的复杂ViewModel . 它可以是 GeneralViewModel ,它在活动和所有片段中与常规片段视图模型一起实例化,因此每个片段中有2个视图模型 .

能够使用视图模型在片段和活动之间进行通信将使得不需要查找活动片段,因为视图模型将提供所需的机制并且还允许使用 Navigation 组件 .

很高兴收到任何信息 .

稍后编辑 . 以下是一些基于以下评论的示例代码 . 这是我的问题的解决方案吗?这可以处理片段和父活动之间的变化,并且它在推荐的一面 .

private GlobalViewModel ():ViewModel(){

      var eventFromActivity:MutableLiveData<Event>
      var eventFromFragment:MutableLiveData<Event>


      fun setEventFromActivity(event:Event){
          eventFromActivity.value = event
      }

      fun setEventFromFragment(event:Event){
          eventFromFragment.value = event
      }

 }

然后在我的活动中

class HomeActivity: AppCompatActivity(){

   onCreate{
       viewModel = ViewModelProviders.of(this, factory)
                .get(GlobalViewModel::class.java)

        viewModel.eventsFromFragment.observe(){
           //based on the Event values, could update toolbar title, could start
           // new fragment, could show a dialog or snackbar
        ....
        }   

     //when need to update the fragment do 
     viewModel.setEventFromActivity(event)
   }
}

然后在所有片段中都有这样的东西

class FragmentA:Fragment(){

  onViewCreated(){

       viewModel = ViewModelProviders.of(this, factory)
                .get(GlobalViewModel::class.java)

        viewModel.eventsFromActivity.observe(){
           // based on Event value, trigger a fun from the fragment 
        ....
        }

        viewModelFragment = ViewModelProviders.of(this, factory)
            .get(FragmentAViewModel::class.java)

        viewModelFragment.some.observe(){
        ....
        }   

  //when need to update the activity do 
     viewModel.setEventFromFragment(event)      
  }

}