Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference a lambda from inside it?

Tags:

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.

like image 560
Pamir Cevikogullari Avatar asked Nov 24 '15 16:11

Pamir Cevikogullari


People also ask

How do lambda expressions work internally?

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.

How is lambda expression represented?

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?

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.

Can lambda expression have return statement?

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.


2 Answers

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     } }) 
like image 60
hotkey Avatar answered Sep 27 '22 21:09

hotkey


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 } 
like image 31
Akexorcist Avatar answered Sep 27 '22 21:09

Akexorcist