从ViewTreeObserver中删除侦听器

时间:2014-10-04 12:11:19

标签: android

我需要监听确切的一个全局布局事件,以初始设置正确的滚动位置。在搜索了一些为什么我对scrollTo(x,y)的调用似乎被忽略之后,我发现只有在知道整个布局后才能以有意义的方式调用它们。所以我正在注册GlobalLayoutListener并将我的电话推迟到scrollTo()

问题是,我只想滚动一次。所以我想我可以简单地叫removeGlobalOnLayoutListener()停止听。这导致了例外:IllegalStateException: This ViewTreeObserver is not alive, call getViewTreeObserver() again。所以我认为我很好,如果观察者不活着它将不会发生任何事件。但遗憾的是:每当布局以某种方式改变时,我的视图都会滚动。

我当前的代码迭代看起来像这样。我可以更改哪些内容以确保只调用scrollToGridPos()一次?我知道我可以在内部类中添加一个本地字段mHasFired,但这对我来说似乎非常肮脏...

final ViewTreeObserver vto = mLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    public void onGlobalLayout() {
        scrollToGridPos(getCenterPoint(), false);
        if (vto.isAlive()) {
            vto.removeGlobalOnLayoutListener(this);
        }
    }
});

1 个答案:

答案 0 :(得分:40)

您应该在mLayout.getViewTreeObserver()中使用onGlobalLayout(),而不是尝试访问。例如

mLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    public void onGlobalLayout() {
        scrollToGridPos(getCenterPoint(), false);
        mLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);        
    }
});