Java 禁用在ViewPager中的某些片段上滑动
我有一个Java 禁用在ViewPager中的某些片段上滑动,java,android,android-viewpager,swipe,touch-event,Java,Android,Android Viewpager,Swipe,Touch Event,我有一个ViewPager,可以禁用或启用滑动触摸: public class ConfigurablePager extends ViewPager { private final AtomicBoolean touchesAllowed = new AtomicBoolean(); ... private boolean touchesAllowed() { return touchesAllowed.get(); } publ
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);
}
}
有些碎片可以刷卡,但另一些不能。寻呼机适配器知道每个片段的滑动行为。此行为可以在ViewPager.OnPageChangeListener
中更改:
@Override
public void onPageSelected(int position) {
if (adapter.isTouchesAllowed(position)) {
views.pager.enableTouches();
} else {
views.pager.disableTouches();
}
}
问题
有时,当我快速滑动片段并同时单击其他片段的选项卡时,viewpager会抛出
IllegalArgumentException
:
致命异常:main java.lang.IllegalArgumentException:指针索引超出范围
在android.view.MotionEvent.nativeGetAxisValue(本机方法)
在android.view.MotionEvent.getX(MotionEvent.java:1979)
在android.support.v4.view.MotionEventCompatEclair.getX(MotionEventCompatEclair.java:32)上
在android.support.v4.view.MotionEventCompat$EclairMotionEventVersionImpl.getX(MotionEventCompat.java:110)
位于android.support.v4.view.MotionEventCompat.getX(MotionEventCompat.java:462)
在android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2080)上
在com.test.debugpager.ConfigurablePager.onTouchEvent(ConfigurablePager.java:39)上
在android.view.view.dispatchTouchEvent(view.java:7384)
在android.view.ViewGroup.DispatchTransformedToucheEvent(ViewGroup.java:2203)上
在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1938)
在android.view.ViewGroup.DispatchTransformedToucheEvent(ViewGroup.java:2231)上
在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1952)上
在android.view.ViewGroup.DispatchTransformedToucheEvent(ViewGroup.java:2209)上
这是因为
ViewPager
保存最后一个指针ID并获得不一致的状态(一些触摸事件由onInterceptTouchEvent
删除),例如,上次触摸事件中的ACTION\u MOVE
带有不正确的MacTivePointId
(请参阅ViewPager.java的来源)
问题
是否可以以其他方式禁用某些片段上的滑动,可能无需覆盖InterceptTouchEvent上的
ViewPager源(onTouchEvent):
解决了的
我仔细阅读了ViewGroup
中的手势识别,并分析了ViewPager
onTouchEvent
来源。在这里,我认识到ViewPager
只对ACTION\u MOVE
事件进行滑动,因此我们不应该只对该操作调用touch回调,我们应该在调用基类ontochevent
之前,遵循baseViewGroup
oninterceptochevent
的oninterceptochevent结果。
根据此规则,我更改了我的
ViewPager
code:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (touchesAllowed()) {
return super.onInterceptTouchEvent(ev);
} else {
if (MotionEventCompat.getActionMasked(ev) == MotionEvent.ACTION_MOVE) {
// ignore move action
} else {
if (super.onInterceptTouchEvent(ev)) {
super.onTouchEvent(ev);
}
}
return false;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (touchesAllowed()) {
return super.onTouchEvent(ev);
} else {
return MotionEventCompat.getActionMasked(ev) != MotionEvent.ACTION_MOVE && super.onTouchEvent(ev);
}
}
@托德萨尔彭:它应该会起作用。当你说有些东西不起作用时,你必须提供一些案例和环境,在这些案例和环境中,这个解决方案不适合你。没有这一点,这一评论毫无用处。
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (touchesAllowed()) {
return super.onInterceptTouchEvent(ev);
} else {
if (MotionEventCompat.getActionMasked(ev) == MotionEvent.ACTION_MOVE) {
// ignore move action
} else {
if (super.onInterceptTouchEvent(ev)) {
super.onTouchEvent(ev);
}
}
return false;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (touchesAllowed()) {
return super.onTouchEvent(ev);
} else {
return MotionEventCompat.getActionMasked(ev) != MotionEvent.ACTION_MOVE && super.onTouchEvent(ev);
}
}