my variable passed into my class constructor can be either Fragment or AppCompactActivity, so I use the following code to check wther it's valid in Glide's .with function.
class XXXX(private val parent: Any)
if (parent is AppCompatActivity || parent is Fragment) {
// Load User Avatar
Glide.with(parent)
.load(dataSet[position].user.avatar)
.into(viewHolder.userAvatar)
}
when I only use parent is AppCompactActivity
or parent is Fragement
, the code works just fine. However, when I use an or
operator, it gives me the following errors:
None of the following functions can be called with the arguments supplied.
with(Activity) defined in com.bumptech.glide.Glide
with(android.app.Fragment) defined in com.bumptech.glide.Glide
with(Context) defined in com.bumptech.glide.Glide
with(View) defined in com.bumptech.glide.Glide
with(androidx.fragment.app.Fragment) defined in com.bumptech.glide.Glide
with(FragmentActivity) defined in com.bumptech.glide.Glide
CodePudding user response:
Kotlin is a static, strongly typed language, so it always requires to understand what is the type of an object and which function exactly is invoked. Well, this is only partially true, it supports virtual functions, but Glide.with()
is overloaded, so it has to be resolved at compile time.
If you use parent is AppCompactActivity
then the compiler is sure parent
is AppCompactActivity
, so when you invoke Glide.with(parent)
it knows it has to use Glide.with(FragmentActivity)
. Similarly, if you use parent is Fragement
then it knows it has to invoke Glide.with(Fragment)
.
If you use parent is AppCompatActivity || parent is Fragment
then the compiler could assume parent is either AppCompatActivity
or Fragment
, but it still doesn't know, which Glide.with()
function to use. This has to be decided at runtime, but the compiler has to resolve this call at compile time, which is not possible.
To fix the problem, you need to provide two separate control flow paths to use the proper with()
function:
val glide = when (parent) {
is AppCompatActivity -> Glide.with(parent)
is Fragment -> Glide.with(parent)
else -> ... // throw exception?
}
glide.load(dataSet[position].user.avatar)
.into(viewHolder.userAvatar)
It looks like we execute exactly the same code for both cases, but in fact this is not true. If you ctrl click on both with()
functions, you'll see they point at different implementations.
If you do this often in your code, you can create an utility function:
fun test() {
glideWith(parent)
.load(dataSet[position].user.avatar)
.into(viewHolder.userAvatar)
}
fun glideWith(context: Any) = when (context) {
is AppCompatActivity -> Glide.with(parent)
is Fragment -> Glide.with(parent)
else -> ... // throw exception?
}