【问题标题】:Passing a Custom Type Object From Fragment to Activity with Navigation Component使用导航组件将自定义类型对象从片段传递到活动
【发布时间】:2020-01-17 18:14:50
【问题描述】:

我想使用Navigation ComponentFragment 中的MediaStream 对象传递给ActivityMediaStream 类属于 WebRTC。因此,我无法触摸它以使其可打包或可序列化以传递对象。

这是片段中的代码:

// Creating a PeerConnection with two callbacks 
// one is triggered when an ICE candidate is received
// the other one is triggered when a MediaStream is received
localPeer = peerConnectionFactory.createPeerConnection(
            rtcConfig,
            object: CustomPeerConnectionObserver("localPeerCreation"){
                override fun onIceCandidate(iceCandidate: IceCandidate?) {
                   // not relevant for this talk 
                }

                override fun onAddStream(mediaStream: MediaStream?) {
                    super.onAddStream(mediaStream)
                    // TODO: create a new Activity and pass media stream to it for displaying
                    StreamsFragmentDirections.actionStreamsFragmentToStreamActivity(mediaStream)
                }
            })!!

正如 TODO 行所暗示的,我最初的目标是将MediaStream 对象传递给应该显示流的新活动。 但我不知道该怎么做。在导航图编辑器中,我选择了<inferred type> 作为mediastream 的类型,但这并没有达到预期的效果。这里,来自导航图xml布局的相关部分:

<activity
        android:id="@+id/streamActivity"
        android:name="com.john.elia.ui.activities.StreamActivity"
        android:label="StreamActivity" >
        <argument 
            android:name="mediaStream" />
</activity>

但是编译器抱怨说它需要一个 Int 但找到了一个 MediaStream。 如何传递 MediaStream 对象?在我发现的所有示例中,它们只显示了如何传递基本类型,如 String、Int 等。自定义类型的对象怎么样?

【问题讨论】:

  • 您只能将 Parcelable 或 Serializable 对象发送到活动,无论是否有导航都是如此。
  • 根据文档支持的自定义大小参数应该是可打包或可序列化的。

标签: android navigation arguments android-architecture-navigation


【解决方案1】:

您可能无法使每种类型的对象都实现Parcelable,但是通过遵循现代应用程序架构的原则,您不必再这样做了,另请参阅Guide to app architecture

一般的想法是将您的数据放在一个存储库(单一事实来源)中,Activitys 和 Fragments 可以通过扩展 ViewModel 的一些自定义类访问该存储库。

因此,一旦您在Fragment 中获得任何类型的数据(MediaStream),您应该将其传递给存储库,导航到下一个 UI 组件并让它在它自己的ViewModel

【讨论】:

  • 啊,好的。 ViewModel...另一个 Android Arch。零件。我想我明白了。谢谢。
  • 请注意,您不能在 Activity 之间共享 ViewModel,因此只有在不同的 Fragment 等(即在单个 Activity 中)共享某些内容时,这才有用。
  • @ianhanniballake - 但我可以从不同的 ViewModel 访问同一个存储库,所以如果我让存储库保留数据,这种方法将起作用
  • 虽然我确信这种方法可能有效,但我不想添加额外的 ViewModel 只是为了来回传递一个对象。我所做的是将整个 WebRTC 流相关的逻辑放到一个已经存在的 Fragment 中,这样所有东西都在一个地方。不需要通过。不再存在了。
  • @aminakoy,如果它适合你,那没关系。在某些情况下,人们注意到 Fragment 已被破坏(例如,由于设备的方向改变),因此必须重新开始整个数据获取操作。这就是 ViewModel 被引入的原因:它确实在方向变化后仍然存在,因此当重新创建 Fragment 时,它可以重新连接到同一个 ViewModel 实例(也可以间接连接到存储库)。这样,已经成功加载的数据不会丢失。但是,再说一遍:如果你的方法适合你,一切都很好:)
猜你喜欢
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多