如何区分android ScrollView的最终用户滚动和程序滚动?
背景:我有一个ScrollView/TextView对,它接收来自外部源的间歇性文本流。它会在每次更新时自动滚动到底部 我希望用户能够通过手动滚动到某个地方来打破自动向下滚动模式,但是我不清楚如何区分手动滚动和我自己正在进行的编程滚动 “我的UI更新”在计时器上运行,以重新绘制缓冲区:如何区分android ScrollView的最终用户滚动和程序滚动?,android,scrollview,Android,Scrollview,背景:我有一个ScrollView/TextView对,它接收来自外部源的间歇性文本流。它会在每次更新时自动滚动到底部 我希望用户能够通过手动滚动到某个地方来打破自动向下滚动模式,但是我不清楚如何区分手动滚动和我自己正在进行的编程滚动 “我的UI更新”在计时器上运行,以重新绘制缓冲区: private Handler outputUpdater = new Handler (); private static String outputBuffer = ""; private static bo
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
的单个调用并不总是位于底部
我希望如果用户手动滚动,我可以决定停止调用fullScroll
不幸的是,仅仅将从“底部,自动模式”到“不在底部”的任何转换视为切换到手动模式的提示似乎还不够,因为各种UI更改似乎也会将滚动视图移离底部(例如,虚拟键盘显示)
问题重述:
如何区分用户启动的滚动和编程滚动 您是否尝试过将
布尔值
与onTouchEvent
一起使用,类似于:
boolean userIntercept = false;
@Override
public boolean onTouchEvent(MotionEvent me) {
int action = me.getAction();
if (action == MotionEvent.ACTION_MOVE) {
userIntercept = true;
}
return super.onTouchEvent(me);
}
然后在输出更新任务中:
// if the output has changed, or the scroll hasn't reached the bottom yet
// then keep scrolling down
if (outputHasChanged || !scrollAtBottom () && !userIntercept) {
ScrollView sv = (ScrollView) findViewById (R.id.scrollView);
sv.fullScroll (View.FOCUS_DOWN);
}
您只需确定将userIntercept
返回到false
的方法,以最适合您的应用程序为准。谢谢,这是最基本的想法。为了完整起见,我现在要做的是:操作移动或操作向下启动手动模式并打开“手指向下”状态。向上操作将关闭“手指向下”状态。如果finger state和atBottom都为真,onScrollChanged和ACTION\u UP都会再次启用自动滚动。有必要根据finger state在onScrollChanged中打破手动模式,因为您可以“轻弹”屏幕进行滚动,并且在滚动完成之前就可以启动操作。