2014-09-19 2 views
6

Я разрабатываю приложение, в котором есть меню ViewPager. Каждый fragment имеет кучу взглядов детей, которые могут быть ListView, ScrollView, LinearLayout и т.д ... Одна из этого fragments имеет настройки кнопки, которая переключает панель настроек (LinearLayout обертки) с ScrollView и некоторыми 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.

После некоторого поиска Google я наткнулся на это:

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 wont, но ListView играет как шарм.

Но проблема все еще остается, я должен добавить это requestDisallowInterceptTouchEvent(true) ко всем дочерним представлениям onTouchEvent, и это не элегантный код.

Итак, мой вопрос: я на правильном пути? Есть ли вообще, чтобы не добавлять этого слушателя ко всем дочерним представлениям панели (конечно, если я должен сделать это самым общим образом)?

Спасибо за ваше время.

ответ

16

Отключение пейджинга должно быть таким же простым, как возврат false от onInterceptTouchEvent и onTouchEvent. Вам не нужно дополнительное обнаружение жестов, чтобы обойти 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

Я такой глупый, конечно, я должен вернуть ложный eheh! Если я вернусь, я украду события движения у детей, и события не будут отправлены в ViewGroup через onTouchEvent(). Благодаря! – GuilhE

Смежные вопросы