Условное использование 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) могут обрабатывать событие, если они оба его получают.


person ovg    schedule 26.04.2016    source источник


Ответы (3)


Попробуй это :

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 по умолчанию, чтобы реализовать свою версию, чтобы не использовать события перемещения.

person NSimon    schedule 26.04.2016

ViewGroup, которая является родительской, сначала получает interceptTouchEvent, и если какой-либо дочерний элемент возвращает true, то родительский элемент не будет получать другие события.

По сути, вы всегда можете вернуть false и реагировать на щелчок, если это действительно событие щелчка. Перетаскивание определяется через пороговое значение

person Petrov Dmitrii    schedule 26.04.2016
comment
Я не могу заставить это работать. Возможно ли, чтобы они оба всегда получали событие? - person ovg; 26.04.2016

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

        // 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

person ovg    schedule 26.04.2016