Почему RecyclerView все еще прокручивается даже после внедрения пользовательского OnTouchListener?

#android #android-recyclerview #scroll #touch-event

#Android #android-recyclerview #прокрутка #сенсорное событие

Вопрос:

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

 recyclerView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return false;
        }
    });
 

Почему recyclerView все еще прокручивается при listener возврате false ? Или, точнее, где обрабатывается и обрабатывается поведение прокрутки?

Я знаю, что return true это означает, что событие касания используется и false означает, что событие касания должно быть передано следующему view в иерархии представлений. На мой взгляд (что, возможно, неверно), возвращаемый тип не должен изменять view поведение. Потому что, когда вы не обрабатываете onTouchListener , это означает, что событие касания (включая поведение прокрутки) не обрабатывается, поэтому recyclerView не должно прокручиваться независимо от типа возвращаемого true значения or false . Что не так в моем восприятии? Надеюсь, я достаточно ясен.

Ответ №1:

Я знаю, что return true означает, что событие касания используется, а false означает, что событие касания должно быть передано следующему представлению в иерархии представлений

Это неверно, правильный порядок при View обработке события касания:

  • View.dispatchTouchEvent() будет вызван первым
  • Отправляет событие на View.OnTouchListener.onTouch() выход if
  • Если не используется, обработайте View.onTouchEvent()

В вашем случае, поскольку ваш return false in View.OnTouchListener.onTouch() , это означает, что вы не используете событие, поэтому событие будет перенаправлено на View.onTouchEvent() of RecyclerView , что объясняет, почему RecyclerView он все еще прокручивается.

Решение 1

Вернитесь true , View.onTouchListener.onTouch() чтобы показать, что RecyclerView он будет использовать все события касания.

 recyclerView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // I will consume all touch events,
        // so View.onTouchEvent() will not be called.
        return true;
    }
});
 

Решение 2

Создайте подкласс, который расширяется RecyclerView и возвращается false , View.onTouchEvent() чтобы показать, что RecyclerView не отображается заинтересованное событие касания.

 public class MyRecyclerView extends RecyclerView {

    public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        // I don't show interested in any touch event.
        return false;
    }
}
 

Это отличная презентация о сенсорной системе Android, вы должны взглянуть.