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);
}
}
);
}
};
为了检测应用栏折叠完成,我调用了 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);
}
}
);
}
};