I am attempting to create a generic extension function that can walk an Android view hierarchy and return the first occurence of a view of a specific type.
The idea would be to invoke the extension as follows (to find the first occurence of a Toolbar
inside of parentView
):
val someView = parentView.findFirstChildRecursive<Toolbar>()
Unfortunately the code below doesn't compile. I guess Kotlin is not happy about having recursive inline functions, but I can't use a reified type without inlining the function.
inline fun <reified T> View.findFirstChildRecursive(): T? {
when (this) {
is T -> return this
is ViewGroup -> {
for (i in 0 until childCount) {
getChildAt(i).findFirstChildRecursive<T>()?.let { return it }
}
}
}
return null
}
I'm a little bit of a Kotlin newbie, so I was hoping someone could explain why or propose a good solution?
I'm gonna add a little bit to Victor Rendina's answer.
You can have two functions: one with the clazz: Class<T>
parameter and the other one inline with reified generic:
inline fun <reified T : View> View.findFirstChildRecursive(): T? {
return findFirstChildRecursive(T::class.java)
}
fun <T: View> View.findFirstChildRecursive(clazz: Class<T>): T? {
if (this::class.java == clazz) {
@Suppress("UNCHECKED_CAST")
return this as T
} else if (this is ViewGroup) {
for (i in 0 until childCount) {
getChildAt(i).findFirstChildRecursive(clazz)?.let { return it }
}
}
return null
}