2014-09-19 22 views
6

我正在開發一個應用程序,它有一個ViewPager作爲菜單。每個fragment有一堆的子視圖可以是ListViewScrollViewLinearLayout等.. 一本fragments的有設置按鈕,切換與ScrollView和一些LinearLayout(按鈕)一設置面板(LinearLayout包裝)和SeekBar作爲孩子。這設置面板動畫與向上或向下動畫幻燈片(解僱時),當它看見我禁用ViewPager分頁:禁用ViewPager分頁的最佳方法

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if (!pagingEnabled && event.getAction() == MotionEvent.ACTION_MOVE) { 
     return true; 
    } 
    return super.onTouchEvent(event); 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent event) { 
    if (!pagingEnabled && event.getAction() == MotionEvent.ACTION_MOVE) { 
     return true; 
    } 
    return super.onInterceptTouchEvent(event); 
} 

public boolean isPagingEnabled() { 
    return pagingEnabled; 
} 

public void setPagingEnabled(boolean pagingEnabled) { 
    this.pagingEnabled = pagingEnabled; 
} 

但這想出了一個問題,每次面板的所有它子視圖不會收到OnTouchEvent,這就是爲什麼我添加了一個GestureDetector.SimpleOnGestureListener

protected class YScrollDetector extends GestureDetector.SimpleOnGestureListener { 
    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
     Log.i(C.TAG, "distanceX " + distanceX + " distanceY " + distanceY); 
     return Math.abs(distanceY) < Math.abs(distanceX); 
    } 
} 

,並改變了我的ViewPageronInterceptTouchEvent到:

@Override 
public boolean onInterceptTouchEvent(MotionEvent event) { 
    if (!pagingEnabled && event.getAction() == MotionEvent.ACTION_MOVE && (mGestureDetector != null && mGestureDetector.onTouchEvent(event))) { 
     return true; 
    } 
    return super.onInterceptTouchEvent(event); 
} 

這個工程,面板按鈕接收他們的onClick,ListView滑動等......但這並不完美,因爲Math.abs(distanceY) < Math.abs(distanceX)它不是那麼準確。如果我快速滑動上下或對角滑動,或者如果輕觸滑動按鈕,onInterceptTouchEvent將返回true,因爲mGestureDetector.onTouchEvent(event)也會返回true

一些谷歌搜索後,我遇到了這個:

viewPager.requestDisallowInterceptTouchEvent(true); 

而且我想是這樣的:

myListView.setOnTouchListener(new View.OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     viewPager.requestDisallowInterceptTouchEvent(true); 
     return false; 
    } 
}); 

而且它的作品真的很好,因爲ViewPager.onInterceptTouchEvent它首先調用MotionEvent.ACTION_DOWN然後myListView.setOnTouchListener這就是所謂的之後並且不允許剩餘的MotionEvent動作(MOVE和UP),並且我可以快速向上,向下滑動,雙向滑動等。ViewPager無法訪問頁面,但ListView滑動像一個魅力。

但問題仍然存在,我必須將此requestDisallowInterceptTouchEvent(true)添加到所有子視圖onTouchEvent,這不是優雅的代碼。

所以我的問題是,我在正確的道路上?無論如何,避免將此偵聽器添加到所有面板子視圖(當然,如果我必須以最通用的方式進行操作)?

謝謝你的時間。

回答

16

禁用分頁應該像從onInterceptTouchEventonTouchEvent返回false一樣簡單。你不應該需要額外的手勢檢測來解決ViewPager。擴展ViewPager這樣的:

public class MyViewPager extends ViewPager { 
    private boolean pagingEnabled = true; 

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

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

    public void setPagingEnabled(boolean pagingEnabled) { 
     this.pagingEnabled = pagingEnabled; 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event) { 
     return pagingEnabled && super.onInterceptTouchEvent(event); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     return pagingEnabled && super.onTouchEvent(event); 
    } 

} 

我使用同樣的原因,同樣的事情(使用不同的名稱)在我的應用程序之一,它肯定工程。

+1

我很愚蠢,當然我必須回報假埃利!如果我返回true,那麼我將偷走孩子們的動作事件,並且事件不會通過onTouchEvent()分派給ViewGroup。謝謝! – GuilhE 2014-09-19 15:05:13