Set click listener on a ViewGroup and detect clicked child view

408 Views Asked by At

So what I have is a custom class that can be inherited by other Fragments. The class has abstract variable - floatingView which is FrameLayout. So any Fragment that inherits this class will have a FrameLayout with X amount of child views - any kind.

Now, my question is - how can I set a click listener in this class with abstract view that holds X amount of child views that can be any type? Setting a simple click listener will always return FrameLayout (parent) id as the one that was clicked, not the child (I need the child one).

I have:

interface Listener {
    fun onFrameLayoutClicked(view: View)
}

and set it up simply as:

frameLayoutParentView.apply {
    setOnClickListener {
        clickListener?.onFrameLayoutClicked(it) //This always return framelayout id and not the childs one (I need child id for logic)
    }
}

Any not too hacky ideas?

1

There are 1 best solutions below

2
bongo On

I'm not sure about how dynamic is your layout in terms of adding/removing view. But if all childs are already placed You can iterate through child views and attach onClick listeners to them.

val onClickListener = View.OnClickListener {
    // Handle click event
}
for (i in 0 until frameLayoutParentView.childCount) {
    val view = frameLayoutParentView.getChildAt(i)
    if (view is View) {
        view.setOnClickListener(onClickListener)
    }
}

Here is also solution for adding listener for all nested views.

fun setOnClickListenerForAllChildren(view: View, onClickListener: View.OnClickListener) {
    if (view is ViewGroup) {
        for (i in 0 until view.childCount) {
            val child = view.getChildAt(i)
            setOnClickListenerForAllChildren(child, onClickListener)
        }
    } else {
        view.setOnClickListener(onClickListener)
    }
}

val container: ViewGroup = findViewById(R.id.container)
val onClickListener = View.OnClickListener {
    // Handle click event
}
setOnClickListenerForAllChildren(container, onClickListener)