我需要监听确切的一个全局布局事件,以初始设置正确的滚动位置。在搜索了一些为什么我对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);
}
}
});
答案 0 :(得分:40)
您应该在mLayout.getViewTreeObserver()
中使用onGlobalLayout()
,而不是尝试访问旧。例如
mLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
scrollToGridPos(getCenterPoint(), false);
mLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});