Pracuję nad aplikacją, która jako menu ma ViewPager
. Każdy fragment
ma kilka widoków podrzędnych, które mogą być ListView
, ScrollView
, LinearLayout
, etc ... Jednym z tego fragments
mają ustawień przycisk, który przełącza panel ustawień (LinearLayout
otoki) z ScrollView
i niektórych LinearLayout
(przyciski) i SeekBar
jako dzieci. Ten ustawienia panel jest animowany ze zjeżdżalnią w górę lub w dół animacji (gdy odwołany) i gdy jest to widoczne ja wyłączyć ViewPager
stronicowania:Najlepszy sposób wyłączenia stronicowania 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;
}
Ale przyszedł z problemem, za każdym razem, gdy panel jest aż wszystko to widoki dziecko nie otrzymałby OnTouchEvent
i dlatego dodałem 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);
}
}
i zmienił mój ViewPager
onInterceptTouchEvent
do:
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (!pagingEnabled && event.getAction() == MotionEvent.ACTION_MOVE && (mGestureDetector != null && mGestureDetector.onTouchEvent(event))) {
return true;
}
return super.onInterceptTouchEvent(event);
}
To działa, przyciski panelu odbierają swoje suwaki onClick, ListView itp ... ale to nie działa tak idealnie, ponieważ Math.abs(distanceY) < Math.abs(distanceX)
nie jest to dokładne. Jeśli przesuję szybko w górę iw dół lub po skosie lub jeśli dotknę przycisku z niewielkim przesunięciem, onInterceptTouchEvent
zwróci true
, ponieważ mGestureDetector.onTouchEvent(event)
również zwróci true
.
Po pewnym google natknąłem to:
viewPager.requestDisallowInterceptTouchEvent(true);
Próbowałem coś takiego:
myListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
viewPager.requestDisallowInterceptTouchEvent(true);
return false;
}
});
I to działa naprawdę dobrze, ponieważ ViewPager.onInterceptTouchEvent
to się nazywa pierwszy z MotionEvent.ACTION_DOWN
a następnie myListView.setOnTouchListener
to się nazywa zaraz po i unieruchamia pozostałe akcje MotionEvent
(MOVE i UP) i mogę szybko przesuwać w górę, w dół, boki, itp. Na stronie ViewPager
przesuwa się, ale ListView
przesuwa się jak zaklęcie.
Ale problem nadal istnieje, muszę dodać to requestDisallowInterceptTouchEvent(true)
do wszystkich widoków podrzędnych onTouchEvent
, a to nie jest elegancki kod.
Moje pytanie brzmi: jestem na dobrej drodze? Czy mimo to należy unikać dodawania tego słuchacza do wszystkich widoków podrzędnych panelu (oczywiście, jeśli muszę, zrobię to w sposób najbardziej ogólny)?
Dziękujemy za poświęcony czas.
Jestem taki głupi, oczywiście muszę zwrócić fałszywe eheh! Jeśli zwrócę prawdę, będę kradł zdarzenia ruchu z potomków i zdarzenia nie zostaną wysłane do ViewGroup przez onTouchEvent(). Dzięki! – GuilhE