共享 ViewModel 以帮助片段和父 Activity 之间的通信

2024-04-10

虽然 JetPack 的导航组件看起来很有前途,但我却找不到实现我想要的东西的方法。

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

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

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

  • 回调方式。有接口onFragmentAction片段中的回调并让活动实现它。所以基本上当用户按下按钮时FragmentA我可以打电话onFragmentAction使用参数,以便活动将触发并启动例如事务以将其替换为FragmentB
  • 实施Navigation来自 JetPack 的组件。虽然我已经尝试过并且看起来非常简单,但我遇到了无法检索当前片段的问题。
  • 使用共享的ViewModel在fragment和activity之间,从fragment中更新它并在activity中观察它。这将是回调的“替代”

2. 自FAB在父活动中,当按下时,我需要能够与当前可见片段进行交互并执行操作。例如,在片段内的回收器视图中添加一个新项目。所以基本上是 Activity 和 Fragment 之间进行通信的一种方式我可以想到有两种方法可以做到这一点

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

因此,正如您所看到的,推荐的导航方法是使用新的“导航”架构组件,但是,目前它缺乏检索当前片段实例的方法,因此我不知道如何在活动和片段。 这可以通过以下方式实现shared ViewModel但这里我有一个缺失的部分:我知道片段到片段的通信可以通过共享 ViewModel 进行。我认为当片段有一些共同点时这是有意义的,例如主/详细场景并且共享相同的视图模型非常有用。

但是,然后在活动和ALL碎片,怎么可能共享ViewModel使用?每个片段都需要它自己的复杂ViewModel。难道它是一个GeneralViewModel它在活动和所有片段中与常规片段视图模型一起实例化,因此每个片段中有 2 个视图模型。

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

很高兴收到任何信息。

稍后编辑。这是基于下面评论的一些示例代码。这是我的问题的解决方案吗?这可以处理片段和父活动之间的更改吗?这是推荐的。

 private class 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)      
  }

}

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

共享 ViewModel 以帮助片段和父 Activity 之间的通信 的相关文章

随机推荐