Ich habe ein ViewPager
die Swipe berührt aktiviert oder deaktiviert werden können:deaktivieren Swipe auf einige Fragmente in ViewPager
public class ConfigurablePager extends ViewPager {
private final AtomicBoolean touchesAllowed = new AtomicBoolean();
...
private boolean touchesAllowed() {
return touchesAllowed.get();
}
public void enableTouches() {
touchesAllowed.set(true);
}
public void disableTouches() {
touchesAllowed.set(false);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return touchesAllowed() && super.onTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return touchesAllowed() && super.onInterceptTouchEvent(ev);
}
}
Einige Fragmente geklaut werden kann, aber andere nicht. Pager-Adapter erkennt das Wischverhalten für jedes Fragment.
@Override
public void onPageSelected(int position) {
if (adapter.isTouchesAllowed(position)) {
views.pager.enableTouches();
} else {
views.pager.disableTouches();
}
}
Das Problem
Manchmal, wenn ich Fragmente sehr schnell, und klicken Sie auf den Reiter für andere Fragment Swipe gleichzeitig viewpager IllegalArgumentException
werfen kann: Dieses Verhalten kann in ViewPager.OnPageChangeListener
geändert werden
FATAL AUSNAHME:
main java.lang.IllegalArgumentException: pointerIndex außerhalb des Bereichs
bei android.view.Moti onEvent.nativeGetAxisValue (native Methode)
bei android.view.MotionEvent.getX (MotionEvent.java:1979)
bei android.support.v4.view.MotionEventCompatEclair.getX (MotionEventCompatEclair.java:32)
bei android. support.v4.view.MotionEventCompat $ EclairMotionEventVersionImpl.getX (MotionEventCompat.java:110)
bei android.support.v4.view.MotionEventCompat.getX (MotionEventCompat.java:462)
bei android.support.v4.view. ViewPager.onTouchEvent (ViewPager.java:2080)
bei com.test.debugpager.ConfigurablePager.onTouchEvent (ConfigurablePager.java:39)
bei android.view.View.dispatchTouchEvent (Vi ew.java:7384)
bei android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2203)
bei android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:1938)
bei android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2231)
bei android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:1952)
bei android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2209)
Es ist happend weil ViewPager
letzte pointerId speichern und inkonsistenten Zustand erhalten (einige t Autscheneignisse fallen um onInterceptTouchEvent
) z. ACTION_MOVE
mit falschen mActivePointerId
von den letzten Berührungsereignis (siehe Quellen ViewPager.java)
Die Frage
Ist es posible Swipe auf einige Fragmente auf andere Weise zu deaktivieren, vielleicht ohne onInterceptTouchEvent
überschrieben?
ViewPager Quellen (onTouchEvent):
case MotionEvent.ACTION_MOVE:
if (!mIsBeingDragged) {
final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float xDiff = Math.abs(x - mLastMotionX);
final float y = MotionEventCompat.getY(ev, pointerIndex);
final float yDiff = Math.abs(y - mLastMotionY);
if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);
if (xDiff > mTouchSlop && xDiff > yDiff) {
if (DEBUG) Log.v(TAG, "Starting drag!");
mIsBeingDragged = true;
requestParentDisallowInterceptTouchEvent(true);
mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop :
mInitialMotionX - mTouchSlop;
mLastMotionY = y;
setScrollState(SCROLL_STATE_DRAGGING);
setScrollingCacheEnabled(true);
// Disallow Parent Intercept, just in case
ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
}
}