Home > Software design >  How to make a function that takes both Activity and Fragment as the context for an argument
How to make a function that takes both Activity and Fragment as the context for an argument

Time:12-21

I have the following function that can take an activity as an argument and when I call it from an Activity it works perfectly. Now that I want to call this function from a fragment but I can see there is an error in the editor saying 'Incompatible types: CargoFragment and Activity'. I tried replacing activity: Activity with context: Context.

The error I have is at '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()
                    }
                }
            }
    }

CodePudding user response:

Don't pass activity to getProductList. As far as I understand, you are passing activity to execute some code when you get a response (success or failure). A better way to implement this is to expose callback lambdas.

Consider this approach:

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

Usage (in your activity and fragment):

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

CodePudding user response:

if this is your viewModel, then u should NEVER have refernce to any context/activity/fragment.

Best approach would be to to have a liveData to hold progress states and let UI (activity or fragment) observe this.

CodePudding user response:

No need to change anything in function parameter. Call it from activity getProductList(this) and call it from fragment getProductList(getActivity()).

  • Related