如何制作一个将 Activity 和 Fragment 作为参数上下文的函数

Posted

技术标签:

【中文标题】如何制作一个将 Activity 和 Fragment 作为参数上下文的函数【英文标题】:How to make a function that takes both Activity and Fragment as the context for an argument 【发布时间】:2021-12-25 22:54:02 【问题描述】:

我有以下可以将活动作为参数的函数,当我从Activity 调用它时,它可以完美运行。现在我想从片段中调用这个函数,但我可以看到编辑器中有一个错误,说“不兼容的类型:CargoFragment 和 Activity”。我尝试用context: Context 替换activity: Activity

我遇到的错误是'is CargoFragment'

    fun getProductList(activity: Activity) 
        mFireStore.collection("abc")
            .get()
            .addOnSuccessListener  
                .....
                .....
                .....

                    productList.add(product)
                
                when (activity) 
                    is CargoActivity -> 
                        activity.success(productList)
                    
                    is CheckoutActivity -> 
                        activity.success(productList)
                    
                    is CargoFragment -> 
                        activity.success(productList)
                    
                
            
            .addOnFailureListener  e ->
                Log.d("CheckTag", e.message!!)
                when (activity) 
                    is CargoActivity -> 
                        activity.hideProgressDialog()
                    
                    is CheckoutActivity -> 
                        activity.hideProgressDialog()
                    
                
            
    

【问题讨论】:

您可以为您的问题添加更多上下文吗?你想达到什么目的?你哪里有这个activity.success(...) 函数? 如您所见,CargoActivityCheckoutActivity 是两个 activities,CargoFragment 是一个 fragment。上面的函数在另一个名为'FirestoreFunctions.kt'的class 添加调用此函数的代码部分。 我可以建议使用这个吗:medium.com/androiddevelopers/… 【参考方案1】:

不要将activity 传递给getProductList。据我了解,当您收到响应(成功或失败)时,您正在传递 activity 来执行一些代码。实现这一点的更好方法是公开回调 lambda。

考虑这种方法:

fun getProductList(onSuccess: (List<Product>) -> Unit, onFailure:() -> Unit) 
    mFireStore.collection("abc")
            .get()
            .addOnSuccessListener 
                ...                  
                    productList.add(product)
                
                onSuccess(productList)
            
            .addOnFailureListener  e ->
                ...
                onFailure()
            

用法(在您的活动和片段中):

getProductList(
    onSuccess =  list ->
        success(list) // whatever you want to do on success
    ,
    onFailure = 
        hideProgressBar() // whatever you want to do on failure
    
)

【讨论】:

这对我来说是新事物。这是比我更好的方法吗? 是的。这将使您的 Firebase 代码与您的 UI 层分离。并使其更有用。您的 firebase 代码不需要依赖于您的活动。只要完成,它就可以调用onSuccessonFailure lambda。因此,与其让getProductList 决定对成功和失败做什么,更好的方法是让调用者决定做什么。 列表总是空的,我一直在检查我是否可以自己修复它,但我不能。 productList 记录到您的getProductList 函数中。验证您是否甚至从 firebase 获取列表。 我登录了很多地方,但我没有得到项目列表,我在想为什么我没有在你评论的那一刻从 Firestore 获取数据。但是,使用我的旧代码,我仍在获取数据。无论如何,让我再检查一次,然后再回复你。【参考方案2】:

如果这是您的 viewModel,那么您永远不应该引用任何上下文/活动/片段。

最好的方法是拥有一个 liveData 来保存进度状态并让 UI(活动或片段)观察这一点。

【讨论】:

【参考方案3】:

无需更改函数参数中的任何内容。 从活动中调用它 getProductList(this) 并从片段中调用它 getProductList(getActivity()).

【讨论】:

我在从fragment 调用它时尝试了FirestoreFunctions().getProductList(requireActivity()),但仍然出现Incompatible types: CargoFragment and Activity 如果 CargoFragment 扩展了 androidx.fragment.app.Fragment 那么 requireActivity() 应该可以工作。我自己试过这个。

以上是关于如何制作一个将 Activity 和 Fragment 作为参数上下文的函数的主要内容,如果未能解决你的问题,请参考以下文章

activity与fragment之间传递数据

Android 兼容包不包含 Activity.getFragmentManager()

Fragment

如何将变量从 Activity 传递到 Fragment,并将其传回?

Activity 与 Fragment通信方式-Android

将水平 RecyclerView 作为项目放置在垂直 RecyclerView 中时的自动滚动问题