如何在 JetPack Navigation 组件中托管 Fragment 的 Activity 中调用导航 Fragments 函数?

Posted

技术标签:

【中文标题】如何在 JetPack Navigation 组件中托管 Fragment 的 Activity 中调用导航 Fragments 函数?【英文标题】:How can I call a navigated Fragment's function in the Activity hosting the fragment via JetPack's Navigation component? 【发布时间】:2020-04-04 07:36:18 【问题描述】:

我从 FragmentManager 的事务切换到 JetPack 的 Navigation 架构组件。在这样做时,我不能再调用: findFragmentById(int) 以便我可以获得对实例化片段的引用,从而从托管它的 Activity 中调用它的函数。

原因是我无法让我的自定义 DialogFragment 在片段本身内实现侦听器,因此我在 Main Activity 中实现了它们。当 DialogFragment 交互时,我希望它通知片段调用一些函数。但是因为我无法在 Fragment 本身中注册监听器,所以完全不知道用户点击了“取消”或“确认”按钮。

Activity 从 DialogFragment 获知用户的操作,然后它应该能够通知 Fragment,以便 Fragment 可以调用它的函数。

如何获得对导航片段的引用以便调用其函数?

【问题讨论】:

【参考方案1】:

首先请检查我对您问题的理解,因为这是我回答的基准:

    你有活动 它承载片段 该片段打开对话片段并想知道用户的对话结果

如果以上是正确的,那么我认为导航目前不支持这样的开箱即用的东西,但是你可以:

    使用共享视图模型(例如在活动级别),它具有某种一次性实时数据,片段被订阅,对话片段发送其选择。所以基本上当对话片段更改实时数据时,托管片段(或任何其他订阅者)会自动接收更改 使用像 Otto 这样的普通旧事件总线,只需在片段级别订阅事件并在对话片段中发出事件?

PS.:这里可能是一次性数据结构:

class OneTimeLiveData<T> : MutableLiveData<T>() 

    private val pending = AtomicBoolean(false)

    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) 
        super.observe(owner, Observer  t ->
            if (pending.compareAndSet(true, false)) 
                observer.onChanged(t)
            
        )
    

    @MainThread
    override fun setValue(t: T?) 
        pending.set(true)
        super.setValue(t)
    

    @MainThread
    fun call() 
        value = null
    

【讨论】:

我最终将 onActivityResult() 与 setTargetFragment() 结合使用,以便通过 onActivityResult() 通知目标片段。在我点击 Confirm 之后,Fragment 可以为所欲为。我想知道我是否出于错误的原因使用 onActivityResult() 。根据我收集到的信息,尽管 ViewModel 是基于 Google 搜索的正确方法。 执行此方法后,我可以删除 MainActivity 中的任何侦听器,从而从 DialogFragment 中删除所有实现/声明(例如 onDialogOptionSelected() ),因为 MainActivity 不需要知道 Dialog被压。我仍然怀疑我做错了什么。 我在导航组件之前使用了方法(onActivityResult/setTargetFragment)。您如何使用导航组件设置目标框架?在我的情况下,对话框只是图形的另一个节点,我没有手动显示它,因此无法设置目标。 我没有设置任何 DialogFragments 作为导航节点。也许这对你也有用。【参考方案2】:

我只需要从应用程序中的活动片段中调用该函数即可使用导航组件。我这样称呼下面的代码。

val searchFragment = supportFragmentManager.fragments[0].childFragmentManager.fragments[0] as SearchFragment
searchFragment.setSearchText(obj.getOriginalValue())

【讨论】:

如果你使用 Glide,这可能会中断。

以上是关于如何在 JetPack Navigation 组件中托管 Fragment 的 Activity 中调用导航 Fragments 函数?的主要内容,如果未能解决你的问题,请参考以下文章

Android Jetpack Navigation:如何在 OnNavigatedListener 中获取目的地的片段实例?

踩坑!Android Jetpack组件间库之Navigation

Android Jetpack导航组件——Navigation的使用

Jetpack学习-Navigation

JetPack架构---Navigation的使用

说到Jetpack路由组件熟悉的只有ARouter框架?今天带你深入理解功能强大的Navigation架构