Условно потреблять MotionEvents
public class CalendarEventView extends LinearLayout {
public CalendarEventView(Context context) {
super(context);
}
public CalendarEventView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CalendarEventView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if((event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP) && event.getAction() != MotionEvent.ACTION_MOVE){
Log.v("move", "click");
return true;
}
return false;
}
}
У меня есть 2 окна просмотра, которые я синхронизирую. Один содержит CalendarEventViews. Они оставались синхронизированными, пока я не добавил onClick и onLongClick к своему CalendarEventView (я установил эти слушатели в viewpager).
Моя проблема в том, что я могу получить либо клики, либо прокрутку, но не оба. Другими словами, как мне разрешить моему CalendarEventView потреблять клики, но позволить его родительскому элементу обрабатывать перемещение / прокрутку.
Примечание: я не возражаю, если и CalendarEventView, и родитель (viewpager) способны обрабатывать событие, пока они оба получают его.
3 ответа
Так что я не мог решить это, но я нашел альтернативу. Я посмотрел на то, как я синхронизировал свои пейджеры, и нашел альтернативу, в которой не нужно использовать сенсорные события. Мой пользовательский вид выше больше не нужен. На всякий случай это кому-нибудь пригодится:
// Synchronise both ViewPagers
// headerColumnViewPager.setOnTouchListener(new OnTouchListener() {
// @Override
// public boolean onTouch(View v, MotionEvent event) {
// contentColumnViewPager.onTouchEvent(event);
// return false;
// }
// });
// contentColumnViewPager.setOnTouchListener(new OnTouchListener() {
// @Override
// public boolean onTouch(View v, MotionEvent event) {
// headerColumnViewPager.onTouchEvent(event);
// return false;
// }
// });
headerColumnViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private int mScrollState = ViewPager.SCROLL_STATE_IDLE;
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
return;
}
contentColumnViewPager.scrollTo(headerColumnViewPager.getScrollX(), contentColumnViewPager.getScrollY());
}
@Override
public void onPageSelected(final int position) { }
@Override
public void onPageScrollStateChanged(final int state) {
mScrollState = state;
if (state == ViewPager.SCROLL_STATE_IDLE) {
contentColumnViewPager.setCurrentItem(headerColumnViewPager.getCurrentItem(), false);
}
}
});
contentColumnViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private int mScrollState = ViewPager.SCROLL_STATE_IDLE;
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
return;
}
headerColumnViewPager.scrollTo(contentColumnViewPager.getScrollX(), headerColumnViewPager.getScrollY());
}
@Override
public void onPageSelected(final int position) { }
@Override
public void onPageScrollStateChanged(final int state) {
mScrollState = state;
if (state == ViewPager.SCROLL_STATE_IDLE) {
headerColumnViewPager.setCurrentItem(contentColumnViewPager.getCurrentItem(), false);
}
}
});
Источник: Синхронизация двух ViewPager с помощью OnPageChangeListener
ViewGroup, который является родительским, получает сначала interceptTouchEvent, и если какой-либо дочерний элемент возвращает true, тогда родительский не получит другие события.
По сути, вы всегда можете вернуть false и реагировать на щелчок, если это действительно событие щелчка. Перетаскивание определяется через порог
Попробуй это:
long eventStarted;
long threshold = 500; //500ms
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
eventStarted = System.currentTimeMillis();
Log.v("move", "action down");
return (true);
case MotionEvent.ACTION_MOVE:
return (System.currentTimeMillis() > (eventStarted + threshold));
case MotionEvent.ACTION_UP:
if (System.currentTimeMillis() <= (eventStarted + threshold)) {
//This is a click
}
eventStarted = 0;
return (true);
}
return false;
}
В основном вы меняете значение по умолчанию OnClickListener
реализовать свою версию, чтобы вы не использовали события перемещения.