Edited at

Measure multiple Fragment/View sizes with Kotlin coroutines

In a complex layout in Android, we need the size of multiple fragments/views. However, in a dynamic layout, these sizes may be changing frequently, and thus we must measure them when they are required.

This measurement cannot always be calculated immediately. For example, if a fragment view has just been created, getLeft()/getTop() etc. will return 0 because the view has no intrinsic size yet. We must therefore post a runnable, or assign a layoutListener, with a callback that returns the fragment size once it is known.

If we require the size of multiple fragments/views, our calling function must wait for all sizes to be returned before it can continue. In Kotlin, coroutines are a useful method of doing this.

This is our calling function, which waits for the result of multiple height measurements. It will return a list of heights in a completion handler.

override fun updateHeights(completion: (List<Int>) -> Unit)  {

val job = launch {

// "fragments" is a predefined list of CustomFragment type
val deferred = fragments.map { fragment ->
async(CommonPool) { fragment.computeHeight() }
}
completion(deferred.map { it.await() })
}
}

This is our customFragment with a suspend function and continuation return value

class CustomFragment: Fragment {

open suspend fun computeHeight() : Int = suspendCoroutine { continuation ->

//call your measuring method with a callback that returns the result
this.measureHeight({ size ->
continuation.resume(size.height)
})
}
}