背景:我有一个 ScrollView / TextView 对,它从外部源接收间歇性的文本流。它会在每次更新时自动滚动到底部。
我希望用户能够通过手动滚动到某个地方来打破自动向下滚动模式,但是我不清楚如何区分手动滚动和我自己正在做的编程滚动。
我的 UI 更新在计时器上运行以缓冲重绘:
private Handler outputUpdater = new Handler ();
private static String outputBuffer = "";
private static boolean outputHasChanged = false;
private static final Object lock = new Object ();
private Runnable outputUpdaterTask = new Runnable () {
public void run () {
synchronized (lock) {
// if the output has changed, update the TextView
if (outputHasChanged) {
TextView tv = (TextView) findViewById (R.id.textView);
tv.setText (outputBuffer);
}
// if the output has changed, or the scroll hasn't reached the bottom yet
// then keep scrolling down
if (outputHasChanged || !scrollAtBottom ()) {
ScrollView sv = (ScrollView) findViewById (R.id.scrollView);
sv.fullScroll (View.FOCUS_DOWN);
}
outputHasChanged = false;
}
outputUpdater.postDelayed (this, 100);
}
};
scrollAtBottom
onScrollChanged
从处理程序获取它的值。
这一切都很好。fullScroll
即使没有文本更新也有必要调用,因为fullScroll
如果有 TextView 更新或虚拟键盘可见性发生变化等,单个调用并不总是到达底部。
我希望如果用户手动滚动,我可以知道做出停止调用的决定fullScroll
。
不幸的是,仅仅将任何从“在底部,自动模式”到“不在底部”的转换视为切换到手动模式的提示似乎还不够,因为各种 UI 更改似乎也将滚动视图从底部移开(例如虚拟键盘显示)。
问题重述: 如何区分用户启动的滚动和程序滚动?