【问题标题】:Send Data from Fragment to Main Activity through NavGraph通过 NavGraph 将数据从 Fragment 发送到 Main Activity
【发布时间】:2020-01-20 18:20:22
【问题描述】:

在我的应用程序中,我使用具有多个片段架构的单个 Activity,并使用导航库在它们之间导航。在其中一个片段中,我有多个类别,每个类别都与一个 ID 相关联。当点击一个类别时,我会使用下面的代码将用户带到相应的类别解释器屏幕。

    val directions = MainNavGraphDirections.launchFragmentWithThisCategoryId(categoryId!!)
            onRoute(AppRoute.Directions(directions))

上面的代码将它们发送到与关联的categoryId 关联的解释器屏幕。一切都很好,直到现在,正确的解释器屏幕基于categoryId 启动。在这个解释器屏幕中,我有一个带有标签chatbot://fragment/wizardintro 的深层链接,它应该让主要活动知道要将用户发送到的特定后续片段。我用下面的代码表示所有可以接收此深层链接的片段。

companion object{
        const val DEEP_LINK = "chatbot://fragment/wizardintro"
    }  

在 MainActivity 中,我有一个方法可以接收所有不同的深度链接意图,并将它们与将使用以下代码启动相应类别片段的标签进行匹配。

 override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.data?.toString().also { deepLink ->
            when (deepLink) {
               IntroductionFragment.DEEP_LINK ->{
                        val categoryId = intent?.getLongExtra("categoryId", 0L)
                        val directions = MainNavGraphDirections.actionGlobalGoalWizard(categoryId)
                        navController.popBackStack()
                        navController.navigate(directions)
                }    
    }

现在,当我尝试在 Main Activity 中检索此 categoryId 并将其传递给下一个片段时,我的问题就出现了。我什么也没得到,只有默认的 Long 被传递。我认为 MainActivity 中的函数覆盖 fun onNewIntent(intent: Intent?) { } 接收任何意图。需要明确的是,这些意图是从解释器片段发送的,该片段在技术上是加载 json 的片段。在 json 中有一个 "route": {"type": "route", "url": "chatbot:///fragment/wizardintro"

在 MainActivity 中,onNewIntent 函数接收这些意图并使用这一行 intent?.data?.toString().also ...将它们解包,然后在 when 语句中选择一个具有匹配 chatbot:///fragment/wizardintro 的片段

我说这一切是为了说主要活动实际上并没有获得 categoryId,它只是选择启动必要的片段,而实际上没有任何与 categoryId 相关的东西

这让我觉得第一次点击的 categoryId 实际上并没有传递给 MainActivity。尽管在我看来,将对象/数据从片段传递到活动似乎并不难。我错过了什么?我可以阅读什么来对自己进行更多的教育? 感谢您的时间和回复!

【问题讨论】:

  • 嘿,您为什么要MainActivity 将您发送到该片段,而该片段实际上可以将您发送到该片段?有什么原因吗?如果没有,我有你的解决方案
  • @Nizar 这是因为我有多个深层链接意图,我使用 MainActivity 根据深层链接附带的标签来确定要启动的片段
  • 您知道在navgraph 中您实际上可以直接深层链接到片段,对吧?
  • 是的,但是这个项目建立的模式需要我将它链接回 MainActivity。对于其他情况,我只是直接深度链接到我需要弹出的片段
  • 所以,我猜 Fragment-To-Fragment 导航不会是一个解决方案,对吧?你有点想通过 MainActivity 传递它,这样你就可以利用你建立的那些 DeepLink,对吧?

标签: android-fragments kotlin android-activity android-navigation android-deep-link


【解决方案1】:

既然我们已经得出MainActivity 没有得到categoryId 的结论,您只需将categoryIddeep-link 一起传递。

但是,从FragmentActivity 不需要任何通信。 您可以通过仅在FragmentFragmentActivityFragment 之间的通信来实现相同的结果。


您要做的是更仔细地查看 AndroidDocs 中的 deep-linksandroid navigationclick here

如您所知,有不同的方法可以解决这个问题,从每个片段的arguments 开始。将categoryId 作为argument 分配给Fragment 将帮助您将navigationControllernavigate 用于新的Fragment,同时将categoryId 传递给它。

现在,我知道您还希望使用deep-link 启动它; here 也有很好的解释。根据docs,可以将arguments放入deep-links,如下方式...

{placeholder_name} 形式的占位符匹配一个或多个字符。例如,http://www.example.com/users/{id} 匹配 http://www.example.com/users/4。导航组件尝试通过将占位符名称匹配到为深度链接目标定义的已定义参数,将占位符值解析为适当的类型。 如果没有定义同名参数,则参数值使用默认字符串类型。


navigation 令人惊叹且功能强大,您只需要了解它实际上可以做什么。你甚至可以用极少的代码将它绑定到BottomNavBar

尝试查看AndroidDocs 关于它的信息,它肯定会在你身上成长。

【讨论】:

  • 感谢@Nizar 分享这个。在阅读了链接的文档后,我意识到将所有意图引导到 MainActivity 中的 onNewIntent 函数似乎是一种反模式。因此,我选择删除该函数并更改 JSON,以便它像 <deepLink app:uri="chatbot://fragment/wizardintro/{categoryId}"/> 一样在 deepLink 中传递 ID。我还从清单中删除了android:launchMode="singleTask",这使我能够使用正确的categoryId 启动所需的片段
  • 听起来你回答了自己的问题;干得好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 2018-01-22
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
相关资源
最近更新 更多