Kotlin这个匿名类

我在这个问题中使用示例代码(View的getWidth()和getHeight()返回0 )。

它有以下代码,

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { view.getViewTreeObserver().removeOnGlobalLayoutListener(this); view.getHeight(); //height is ready } }); 

我就这样写在Kotlin上

 image_view.viewTreeObserver.addOnGlobalLayoutListener{ image_view.viewTreeObserver.removeOnGlobalLayoutListener { this } Log.d("Should be called once", "Height = " + image_view.height + ", Width = " + image_view.width) }; 

结果是,

 11-22 19:18:33.319 4754-4754/loser.qrcode D/Should be called once: Height = 672, Width = 672 11-22 19:18:33.328 4754-4754/loser.qrcode D/Should be called once: Height = 672, Width = 672 

所以,这被称为两次。 也就是说, removeOnGlobalLayoutListener不起作用。 我应该用什么来代替this

这里的问题是Kotlin正在取消removeOnGlobalLayoutListener将需要一个SAMexpression式 。 然后当你传递{ this } ,你只是创建另一个OnGlobalLayoutListener实例,在这里是等价的:

 view.getViewTreeObserver().removeOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { YourOuterClass.this; } }); 

而这个监听器在当前监听器列表中不存在

为了解决这个问题,你必须声明你的OnGlobalLayoutListener作为一个对象,而不是一个lamba,像这样你可以引用正确的“ this ”,并在调用之后正确地移除listener。

 image_view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { image_view.viewTreeObserver.removeOnGlobalLayoutListener(this) Log.d("Should be called once", "Height = " + image_view.height + ", Width = " + image_view.width) } })