共享的ViewModel有助于片段与父级活动之间的通信

时间:2018-07-25 12:31:42

标签: android android-architecture-components android-viewmodel android-jetpack android-livedata

JetPack的导航组件看上去很有希望,但是我到了一个找不到实现自己想要的东西的地方。

让我们看一下示例应用程序屏幕:

该应用程序有一个主要活动,一个顶部的工具栏,一个底部的工具栏,并带有fab。 我面临着两个挑战,我想让它们以正确的方式进行。

1。我需要实现片段事务,以便允许基于用户交互来替换屏幕上的片段。 我可以想到并实现三种方法:

  • 回调方式。片段中有一个接口onFragmentAction回调,并有活动来实现它。因此,基本上,当用户按下FragmentA中的按钮时,我可以使用参数调用onFragmentAction,这样该活动将触发并开始执行例如用FragmentB代替它的交易
  • Jet的
  • 实现Navigation组件。虽然我已经尝试过了,而且看起来很简单,但是由于无法检索当前片段,我遇到了一个问题。
  • 在片段和活动之间使用共享的ViewModel,从片段中对其进行更新并在活动中进行观察。这将是回调的“替代”

2。由于FAB在父活动中,因此在按下时,我需要能够与当前可见片段进行交互并执行操作。例如,在片段内的recyclerview中添加新项目。因此,基本上是一种在活动和片段之间进行交流的方法 我可以通过两种方法来做到这一点

  • 如果不使用Navigation,那么我可以使用findFragmentById并检索当前片段并运行公共方法来触发操作。
  • 在片段和活动之间使用共享的“ ViewMode”,从活动中对其进行更新并在片段中进行观察。

因此,如您所见,推荐的导航方法是使用新的“ Navigation”架构组件,但是,目前它缺少检索当前片段实例的方法,因此我不知道如何在活动和片段之间进行交流。 这可以通过shared ViewModel来实现,但是在这里我有一个遗漏的地方:我知道可以使用共享的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)      
  }

}

0 个答案:

没有答案