Intereting Posts
Отсутствует звонок, чтобы отменить регистрацию получателя HapticFeedbackBroadcastReceiver, который я никогда не регистрировал AChartEngine и Android Studio Для чего используется ids.xml? Как я могу вернуться обратно в свою активность из окна настроек GPS NotifyDataSetChanged () не обновляющий адаптер Функция прокрутки списка в виде прокрутки Android: Фрагмент предпочтений с фрагментом навигационного ящика Камера Android – Как я могу взять конкретный «прямоугольник» из массива байтов? Идентификационный RTL-язык в Android Как получить доступ к com.android.internal.R.bool в приложении? Как масштабировать веб-сайт для мобильных устройств? SlidingDrawer не может иметь НЕОБХОДИМЫЕ измерения Загрузка пользовательского класса в Dalvik с помощью Gradle (Android New Build System) Android: Как установить содержимое Редактировать текст с помощью кнопки? Является ли какая-нибудь функция быстрой, похожей на R.java в Android?

Предотвращение использования RecyclerView для использования событий касания

проблема

Я пытаюсь смоделировать точное поведение приложения Google Play.

В настоящее время, когда вы прокручиваете категорию, например «Лучшие игры», и вы касаетесь списка, эта ячейка, а также RecyclerView обрабатывает событие касания, вы можете сказать, что они оба справляются с этим из-за пульсации, появляющейся, когда вы держите палец Вниз, а также прокрутка, останавливающаяся. Или если вы нажмете на ячейку, пока список все еще перемещается, содержимое сразу открывается.

Поведение по умолчанию заключается в том, что прокрутка мгновенно останавливается, если вы поместите свой палец вниз, пока он движется, и для этого он должен потреблять это событие касания, то есть клетке никогда не рассказывают об этом прикосновении. Это невероятно раздражает, когда основное содержимое вашего приложения находится в RecyclerView и если пользователь постоянно прокручивается, а затем щелкает по ячейке, он требует, чтобы они дважды щелкнули, поскольку первый клик был поглощен остановкой прокрутки, даже если список был Едва двигаясь.

Что я пробовал до сих пор

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

Затем я попытался захватить событие касания с помощью onInterceptTouchEvent и вручную сказать, что его касаются;

 @Override public boolean onInterceptTouchEvent(MotionEvent event) { View myCell = recyclerView.findChildViewUnder(event.getX(), event.getY()); myCell.dispatchTouchEvent(event); return super.onInterceptTouchEvent(event); } 

Здесь dispatchTouchEvent , похоже, ничего не делал, хотя представление, которое я получал, имело соответствующий тег, который я установил в адаптере.

Я пробовал снимать эту проблему с помощью моего пулемета кода под любым углом; Играя с requestDisallowInterceptTouchEvent , вручную вызывая onTouch и переопределяя все способы прослушивания RecyclerView и других.

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

Пожалуйста помоги! 🙂 Благодаря.

Решение

Благодаря Jagoan Neon найдено решение. Я закончил тем, что закрыл свой ответ внутри пользовательского RecyclerView для удобства использования.

 public class MultiClickRecyclerView extends RecyclerView { public MultiClickRecyclerView(Context context) { super(context); } public MultiClickRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public MultiClickRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && this.getScrollState() == RecyclerView.SCROLL_STATE_SETTLING) { this.stopScroll(); } return super.onInterceptTouchEvent(event); } } 

Solutions Collecting From Web of "Предотвращение использования RecyclerView для использования событий касания"

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

 RecyclerView.OnItemTouchListener mOnItemTouchListener = new RecyclerView.OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { if (e.getAction() == MotionEvent.ACTION_DOWN && rv.getScrollState() == RecyclerView.SCROLL_STATE_SETTLING) { Log.d(TAG, "onInterceptTouchEvent: click performed"); rv.findChildViewUnder(e.getX(), e.getY()).performClick(); return true; } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) {} @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {} }; 

Почему ACTION_DOWN и SCROLL_STATE_SETTLING?

Событие движения ACTION_DOWN будет срабатывать при нажатии на RecyclerView, и в этот точный момент времени RecyclerView изменяет свое состояние прокрутки на SCROLL_STATE_SETTLING, когда он пытается остановить прокрутку. И это именно то, когда вы хотите выполнить щелчок.

И не забудьте вернуть true, чтобы вы сообщали своему RecyclerView, что вы поглотили MotionEvent. В противном случае ваш вызов performClick () может вызываться более одного раза.

Добавьте его в свой RecyclerView at onResume и удалите его в onPause, и вы все настроены;)

ОБНОВИТЬ

Добавьте нулевой checker, когда вы делаете findChildViewUnder – он возвращает null, когда вы не касаетесь определенной ячейки.

 View childView = rv.findChildViewUnder(e.getX(), e.getY()); if (childView != null) childView.performClick(); 

ОБНОВЛЕНИЕ 2

Оказывается, что достаточно остановить прокрутку RecyclerView. Сделайте это вместо этого:

 @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { if (e.getAction() == MotionEvent.ACTION_DOWN && rv.getScrollState() == RecyclerView.SCROLL_STATE_SETTLING) rv.stopScroll(); return false; }