从ViewTreeObserver删除侦听器 [英] Remove listener from ViewTreeObserver

查看:146
本文介绍了从ViewTreeObserver删除侦听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要听确切的一个全局布局事件以初始设置正确的滚动位置.在稍微搜寻了为什么我对scrollTo(x,y)的调用似乎被忽略之后,我发现只有在知道整个布局后才能以有意义的方式调用它们.因此,我正在注册GlobalLayoutListener,然后将呼叫推迟到scrollTo().

I need to listen for exact one global layouting event to initially set correct scrolling positions. After searching a little why my calls to scrollTo(x,y) seem to be ignored I discovered these can only be called in an meaningful way once the whole layout is known. So I am registering a GlobalLayoutListener and defer my call to scrollTo().

问题是,我只想滚动一次.所以我想我可以简单地调用removeGlobalOnLayoutListener()停止收听.这导致异常:IllegalStateException: This ViewTreeObserver is not alive, call getViewTreeObserver() again.所以我认为我很好,如果观察者还没有活着,将不会触发任何事件.但不幸的是,每当布局发生某种更改时,我的视图就会滚动.

The problem is, that I only want to do this scrolling once. So I figured I could simply call removeGlobalOnLayoutListener() to stop listening. That resulted in a Exception: IllegalStateException: This ViewTreeObserver is not alive, call getViewTreeObserver() again. So I thought I am fine, if the Observer is not alive it won't fire any events. But unfortunately it does: My view is scrolled every time the layout somehow changes.

我当前的代码迭代看起来像这样.我可以更改什么以确保对scrollToGridPos()的调用仅发生一次?我知道我可以将一个本地字段mHasFired添加到内部类中,但这对我来说似乎很肮脏……

My current iteration of the code looks like this. What could I change to make sure the call to scrollToGridPos() only takes place once? I know I could just add a local field mHasFired to the inner class but that seems like very dirty hack to me ...

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

推荐答案

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

You should just be using mLayout.getViewTreeObserver() in onGlobalLayout(), rather than trying to access the old one. Eg.

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

这篇关于从ViewTreeObserver删除侦听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆