Условно консумирайте 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);
            }
        }
    });

Източник: Синхронизиране на два ViewPagers с помощта на OnPageChangeListener

person ovg    schedule 26.04.2016