Как отличить прокрутку конечного пользователя Android ScrollView от программной прокрутки?

Справочная информация: у меня есть пара ScrollView / TextView, которая получает прерывистый поток текста из внешнего источника. Он автоматически прокручивается вниз при каждом обновлении.

Я хотел бы, чтобы пользователь мог вырваться из этого режима автоматической прокрутки вниз, вручную прокручивая куда-нибудь, однако мне неясно, как отличить ручную прокрутку от программной прокрутки, которую я делаю сам.

мое обновление пользовательского интерфейса выполняется по таймеру для буфера перерисовывает:

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.

к сожалению Кажется, что недостаточно просто рассматривать любой переход от" внизу, автоматический режим "к" не внизу " в качестве подсказки для перехода в ручной режим, потому что различные изменения пользовательского интерфейса, похоже, также перемещают вид прокрутки снизу (например, показ виртуальной клавиатуры).

Вопрос Переформулировать: Как отличить инициированную пользователем прокрутку от программной прокрутки?

1 ответов


вы пробовали использовать boolean С 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);
}

затем в 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 to false, в зависимости от того, что лучше всего подходит для вашего приложения.