1

So I have this extension function for ViewGroup :

inline fun <reified T : View> ViewGroup.allViewsOfType(action: (T) -> Unit) 
{
    val views = Stack<View>()

    afterMeasured {
        views.addAll((0 until childCount).map(this::getChildAt))
    }

    while (!views.isEmpty()) {
        views.pop().let {
            if (it is T) action(it)
            if (it is ViewGroup) {
                afterMeasured {
                    views.addAll((0 until childCount).map(this::getChildAt))
                }
            }
        }
    }
}

And I use it like this:

tabs.allViewsOfType<Button> { Log.i("Dale", it.text.toString()) }

But somehow it doesn't work. Anything that I'm doing wrong?

Btw, tabs is a LinearLayout that contains three Buttons in it.

Dale Julian
  • 1,560
  • 18
  • 35

1 Answers1

2

Why do you use afterMeasure in the particular case?

  1. I just removed afterMeasure:

    inline fun <reified T : View> ViewGroup.allViewsOfType(action: (T) -> Unit) {
        val views = Stack<View>()
    
        views.addAll((0 until childCount).map(this::getChildAt))
    
        while (!views.isEmpty()) {
            views.pop().let {
                if (it is T) action(it)
                if (it is ViewGroup) {
                    views.addAll((0 until childCount).map(this::getChildAt))
                }
            }
        }
    }
    
  2. Replaced Log.i() logger with simple Kotlin's println():

    tabs.allViewsOfType<Button> {
        println("Dale: ${it.text}")
    }
    
  3. And now your function works just fine:

    I/System.out: Dale: Button 4
                  Dale: Button 3
                  Dale: Button 2
                  Dale: Button 1
    
letner
  • 621
  • 6
  • 11