AppBarLayout:如何移除OnOffsetChangedListener

AppBarLayout: how to removeOnOffsetChangedListener

为了检测应用栏折叠完成,我调用了 addOnOffsetChangedListener。在听众的 onOffsetChanged 中,我捕捉并处理了崩溃的时刻。然后我需要停止监听偏移量变化。

在大多数示例中,这里是从 onOffsetChanged 内部调用 removeOnOffsetChangedListener(this)。但是查看 AppBarLayout.java 我看到:

private void dispatchOffsetUpdates(int offset) {
    // Iterate backwards through the list so that most recently added listeners
    // get the first chance to decide
    if (mListeners != null) {
        for (int i = 0, z = mListeners.size(); i < z; i++) {
            final OnOffsetChangedListener listener = mListeners.get(i);
            if (listener != null) {
                listener.onOffsetChanged(this, offset);
            }
        }
    }
}

因此,如果安装了多个侦听器,调用 removeOnOffsetChangedListener(this) 自然会导致 IndexOutOfBoundsException

我错过了什么吗?是否有 安全 方式 'unsubscribe' 监听偏移量更新?

有趣的是,如果他们的代码确实按照评论所说的进行操作,这就不是问题。无论如何,我们可以通过将对 removeOnOffsetChangedListener() 的调用放在 Runnable 中并将其发布到 AppBarLayout 中的 onOffsetChanged() 来延迟删除,而不是直接在那里调用它。

例如:

AppBarLayout.OnOffsetChangedListener listener = new AppBarLayout.OnOffsetChangedListener() {
    @Override
    public void onOffsetChanged(final AppBarLayout abl, int offset) {
        abl.post(new Runnable() {
                @Override
                public void run() {
                    abl.removeOnOffsetChangedListener(listener);
                }
            }
        );
    }
};