【问题标题】:How to make a function that takes both Activity and Fragment as the context for an argument如何制作一个将 Activity 和 Fragment 作为参数上下文的函数
【发布时间】: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/…

标签: android kotlin android-fragments


【解决方案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() 应该可以工作。我自己试过这个。
    猜你喜欢
    • 2010-11-04
    • 2020-10-31
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多