如何阻止ExpandableListView窃取儿童触摸事件?

时间:2013-11-20 16:49:25

标签: android

我在ExpandableListView的组视图(节头)中有一个ViewPager。正如预期的那样,ViewPager的滚动有时会变得不稳定,很可能是因为ExpandableListView试图拦截触摸事件。作为解决方案,我试图阻止ExpandableListView拦截触摸事件,如果它们是针对ViewPager的。所以,这就是我所做的。

private void fixViewPager(ViewPager vp) {
    vp.setOnTouchListener(new ViewPager.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getAction();
            switch (action) {
            case MotionEvent.ACTION_DOWN:
                // Disallow ScrollView to intercept touch events.
                Logger.log("Disabling event stealing");
                v.getParent().requestDisallowInterceptTouchEvent(true);
                break;

            case MotionEvent.ACTION_UP:
                // Allow ScrollView to intercept touch events.
                Logger.log("Enabling event stealing");
                v.getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }

            // Handle ListView touch events.
            v.onTouchEvent(event);
            return true;
        }
    });     
}

但是,触摸侦听器永远不会获得ACTION_DOWN事件。它似乎只能获得ACTION_UP事件。我该怎么做才能解决我的问题?谢谢!

2 个答案:

答案 0 :(得分:3)

我发布问题后不久,我找到了这个答案https://stackoverflow.com/a/9770373/1036017。基于此我将我的代码更改为以下内容。现在,一旦在ViewPager中开始水平滚动,ViewPager就会阻止ExpandableListView窃取触摸事件。

private void fixViewPager(ViewPager vp) {
    vp.setOnTouchListener(new ViewPager.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            view.getParent().requestDisallowInterceptTouchEvent(true);
            switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_UP:
                    Logger.log("Disabling event stealing.");
                    view.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
            }
            return false;
        }
    });     
}

答案 1 :(得分:0)

解决方案是在viewPager中正确使用 requestDisallowInterceptTouchEvent()方法。使用以下自定义viewpager类:

public class CustomViewPager extends ViewPager {
 boolean xScored = false, yScored = false;

 public CustomViewPager(Context context) {
    super(context);
 }

 public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
 }

 @Override
 public boolean onTouchEvent(MotionEvent ev) {
    mGestureDetector.onTouchEvent(ev);
    if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
        xScored = false;
        yScored = false;
        requestDisallowInterceptTouchEvent(false);
    }
    return super.onTouchEvent(ev);
 }

  GestureDetector.SimpleOnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
     @Override
     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        if (!yScored && Math.abs(distanceX) > Math.abs(distanceY)) {
            xScored = true;
            yScored = false;
        }
        if (xScored) {
            requestDisallowInterceptTouchEvent(true);
        } else if (!xScored && Math.abs(distanceY) > Math.abs(distanceX)) {
            xScored = false;
            yScored = true;
            requestDisallowInterceptTouchEvent(false);
        }
        return true;
     }

  };
  GestureDetector mGestureDetector = new GestureDetector(getContext(), mOnGestureListener);
 }