I am trying to get height of a view in onCreate method but I couldn't find any way to remove OnGlobalLayoutListener.
In Java (working):
containerLayout.getViewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { containerLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); int width = layout.getMeasuredWidth(); int height = layout.getMeasuredHeight(); } });
In Kotlin (not accepting "this"):
containerLayout.viewTreeObserver.addOnGlobalLayoutListener { containerLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) Toast.makeText(applicationContext, "size is "+ containerLayout.height,Toast.LENGTH_LONG).show() }
Is there any reference or example for this problem? Thanks.
Every lambda expression in Java is internally mapped to a functional interface. The functional interface to which a lambda expression will be mapped is determined by the compiler from its surrounding context at compile time. // A lambda expression that accepts no arguments and returns void () -> System.
For Lambda expressions, the compiler doesn't translate them into something which is already understood by JVM. Lambda syntax that is written by the developer is desugared into JVM level instructions generated during compilation, which means the actual responsibility of constructing lambda is deferred to runtime.
What is the return type of lambda expression? Explanation: Lambda expression enables us to pass functionality as an argument to another method, such as what action should be taken when someone clicks a button.
A return statement is not an expression in a lambda expression. We must enclose statements in braces ({}). However, we do not have to enclose a void method invocation in braces.
Referencing a lambda from inside it is not supported.
As a workaround, you might use anonymous object instead of lambda SAM-converted to Java functional interface OnGlobalLayoutListener
:
containerLayout.viewTreeObserver.addOnGlobalLayoutListener(object: OnGlobalLayoutListener { override fun onGlobalLayout() { // your code here. `this` should work } })
What's about extension like this?
import android.annotation.SuppressLint import android.os.Build import android.view.View import android.view.ViewTreeObserver inline fun View.doOnGlobalLayout(crossinline action: (view: View) -> Unit) { val vto = viewTreeObserver vto.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { @SuppressLint("ObsoleteSdkInt") @Suppress("DEPRECATION") override fun onGlobalLayout() { action(this@doOnGlobalLayout) when { vto.isAlive -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { vto.removeOnGlobalLayoutListener(this) } else { vto.removeGlobalOnLayoutListener(this) } } else -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { viewTreeObserver.removeOnGlobalLayoutListener(this) } else { viewTreeObserver.removeGlobalOnLayoutListener(this) } } } } }) }
Finally, you can call OnGlobalLayoutListener from View directly
val view: View = ... view.doOnGlobalLayout { val width = view?.measuredWidth val height = view?.measuredHeight }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With