Подтвердить что ты не робот

Удалить слушателя из ViewTreeObserver

Мне нужно прослушивать точное одно глобальное событие компоновки, чтобы первоначально установить правильные позиции прокрутки. После небольшого поиска, почему мои вызовы на 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);
        }
    }
});
4b9b3361

Ответ 1

Вы должны просто использовать mLayout.getViewTreeObserver() в onGlobalLayout(), а не пытаться получить доступ к старой. Например.

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