android - 如何区分 android ScrollView 的最终用户滚动与程序滚动?

标签 android scrollview

背景:我有一个 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);
    }
};

scrollAtBottomonScrollChanged 处理程序中获取它的值。

一切正常。即使没有文本更新,也有必要调用 fullScroll,因为如果正在进行 TextView 更新,则对 fullScroll 的单个调用并不总是到达底部,或者虚拟键盘可见性改变等

我希望如果用户手动滚动,我可以知道做出停止调用 fullScroll 的决定。

不幸的是,将“在底部,自动模式”到“不在底部”的任何转换视为切换到手动模式的提示似乎还不够简单,因为各种 UI 更改似乎将 ScrollView 从底部也(例如虚拟键盘显示)。

重述问题: 如何区分用户启动的滚动和程序滚动?

最佳答案

您是否尝试过将 booleanonTouchEvent 一起使用,类似于:

boolean userIntercept = false;
@Override
public boolean onTouchEvent(MotionEvent me) {
    int action = me.getAction();
    if (action == MotionEvent.ACTION_MOVE) {
            userIntercept = true;
    }
    return super.onTouchEvent(me);
}

然后在您的 outputUpdaterTask 中:

// 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 的方式,以最适合您的应用程序为准。

关于android - 如何区分 android ScrollView 的最终用户滚动与程序滚动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16110552/

相关文章:

android - 在 ScrollView 中实现向左/向右滑动

android - 来自此 Android 客户端应用程序 <empty> 的请求被阻止 - Google API 错误 Flutter

php - 通过 PHP + JSON 从 MySql 获取状态

android - Android 中的错误 "Dataset and renderer should be not null and should have the same number of series"

android - ViewPager 内的 ScrollView

ios - 在 UITextView 中捕获滚动 Action

android - 在 Android 中获取当前国家/地区 - 旅行

java - VideoView,为视频添加再次播放按钮

ios - SwiftUI:从 ScrollView 中的底部对齐构建 View

java - ScrollView 在 android 中不完全滚动