【问题标题】:Conditionally consume MotionEvents有条件地使用 MotionEvents
【发布时间】:2016-08-20 06:54:36
【问题描述】:
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)是否都能够处理事件,只要它们都收到它。

【问题讨论】:

    标签: android android-custom-view motionevent consuming


    【解决方案1】:

    所以我无法解决它,但我找到了替代方案。我查看了我是如何同步我的浏览器的,并找到了一个不需要使用触摸事件的替代方案。不再需要我上面的自定义视图。以防万一它对某人有用:

            // 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);
                }
            }
        });
    

    来源:Synchronizing two ViewPagers using OnPageChangeListener

    【讨论】:

      【解决方案2】:

      ViewGroup作为parent,首先接收interceptTouchEvent,如果有的child返回true,那么parent就不会再接收其他事件了。

      基本上,如果它实际上是点击事件,您总是可以返回 false,并对点击做出反应。通过treshold检测到拖动

      【讨论】:

      • 我无法让它工作。他们俩有可能总是得到这个事件吗?
      【解决方案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 来实现你的版本,这样你就不会消耗移动事件。

      【讨论】:

        猜你喜欢
        • 2011-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-20
        相关资源
        最近更新 更多