2013-11-20 49 views
3

我在ExpandableListView的組視圖(節標題)中有一個ViewPager。正如所料,ViewPager的滾動有時會變得不連貫,很可能是因爲ExpandableListView試圖攔截觸摸事件。作爲解決方案,我試圖阻止ExpandableListView攔截觸摸事件,如果它們是爲ViewPager的。所以,這就是我所做的。如何停止ExpandableListView竊取兒童觸摸事件?

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事件。我能做些什麼來解決我的問題?謝謝!

回答

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

的解決方案是正確使用方法requestDisallowInterceptTouchEvent()中viewPager。使用以下自定義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); 
}