如果我将lambda作为侦听器传递,我可以从lambda中删除侦听器

时间:2016-08-17 19:15:04

标签: android lambda listener

在Android应用程序中,我有以下方法:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    final View view = getView();
    if (view == null) return;
    view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
        view.post(() -> {
            if (mIsTablet) {
                mImageFlipper.getLayoutParams().height =
                        ViewUtil.setHeightForAspectRatio(view.getWidth(), ViewUtil.PORTRAIT);
            } else {
                mImageFlipper.getLayoutParams().height =
                        ViewUtil.setHeightForAspectRatio(mDisplayMetrics.widthPixels, ViewUtil.PORTRAIT);
            }
            view.getViewTreeObserver();
        });

    });
}
事情是,我喜欢lambdas。它们简洁,干净,富有表现力。

然而,在侦听器被触发后,我想删除(最好是从lambda本身内部)。

问题很简单:如何删除监听器?

更抽象的问题是:如何从内部引用lambda?

1 个答案:

答案 0 :(得分:1)

来自oracle tutorial

  

访问封闭范围的局部变量

  像本地和匿名类一样,lambda表达式可以捕获   变量;他们对本地变量具有相同的访问权限   封闭范围。但是,与本地和匿名类不同,lambda   表达式没有任何阴影问题(请参阅阴影了解更多信息   信息)。 Lambda表达式是词法范围的。这意味着   他们不会从超类型继承任何名称或引入新名称   范围界定

我认为这意味着你无法从内部引用lambda。

为了解决你的问题,我认为你应该创建将lambda赋值给变量并从lambda

中引用变量
ViewTreeObserver.OnGlobalLayoutListener layoutListener;

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    // ...
    layoutListener = () -> {
        // ...
        view.getViewTreeObserver().removeOnGlobalLayoutListener(layoutListener);
    };

或者这次放弃lambda ......