【问题标题】:Remove listener from ViewTreeObserver从 ViewTreeObserver 中移除监听器
【发布时间】:2014-11-29 07:45:06
【问题描述】:

我需要监听一个确切的全局布局事件来初始设置正确的滚动位置。在搜索了一下为什么我对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);
        }
    }
});

【问题讨论】:

  • 对我来说这似乎不是一个黑客。或者,如果您可以覆盖它,您也可以在 View.onLayout 中执行相同的操作。这似乎更适合我。

标签: android


【解决方案1】:

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

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

【讨论】:

  • 看起来不错,但 removeGlobalOnLayoutListener 已弃用。有没有其他的方法可以移除监听器?
  • 我正在使用 removeOnGlobalLayoutListener()
  • 通常他们会说在弃用的情况下使用什么,应该在 Java 文档中说明。
猜你喜欢
  • 2013-07-14
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
  • 2017-11-11
  • 1970-01-01
  • 2023-03-03
  • 2011-12-30
  • 1970-01-01
相关资源
最近更新 更多