禁用在ViewPager中的某些片段上滑动

基里尔

我有一个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

致命异常:
主java.lang.IllegalArgumentException:pointerIndex超出范围,
在android.support.v4.view
上的android.view.MotionEvent.getX(MotionEvent.java:1979)
处的android.view.MotionEvent.nativeGetAxisValue (Native方法)。 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.dispatchTransformedTouchEvent(ViewGroup.java:2203)
在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1938)
在android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2231)
在android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2231)在。
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)上的ViewGroup.dispatchTouchEvent (ViewGroup.java:1952)

之所以发生这种情况,是因为ViewPager保存了上一个pointerId并获得了不一致的状态(某些触摸事件已被删除onInterceptTouchEvent),例如ACTION_MOVEmActivePointerId一次触摸事件中的状态不正确(请参见ViewPager.java的源代码)

问题
是否有可能以其他方式禁用某些片段上的滑动,而可能不会覆盖onInterceptTouchEvent

ViewPager来源(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);
            }
        }
    }
基里尔

解决了

我已经专心阅读了有关手势识别的android指南ViewGroup并对其进行了分析ViewPager onTouchEvent在这里,我认识到ViewPager只为ACTION_MOVE事件滑动,因此我们不应该仅为此操作调用touch回调,并且应该ViewGroup onInterceptTouchEvent在调用基类之前服从基结果onTouchEvent

根据此规则,我更改了ViewPager代码:

@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);
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

需要禁用CollapsingToolbarLayout上某些片段的扩展

来自分类Dev

使用ViewPager的CollapsingToolbarLayout中的片段不会向下滑动

来自分类Dev

使用ViewPager的CollapsingToolbarLayout中的片段不会向下滑动

来自分类Dev

如何在ViewPager中禁用特定页面滑动

来自分类Dev

在片段级别与ViewPager一起应用了滑动手势,但禁用了默认滑动

来自分类Dev

在Android上的ViewPager中替换当前片段

来自分类Dev

在 RecyclerView 单击上替换 ViewPager 中的片段

来自分类Dev

如何在某些活动中而不是在片段中禁用返回

来自分类常见问题

禁用在Android中打开导航抽屉的滑动手势

来自分类Dev

滑动后刷新Android Viewpager片段

来自分类Dev

滑动后刷新Android Viewpager片段

来自分类Dev

片段内的 OnTouchListener 停止 Viewpager 滑动事件

来自分类Dev

禁用在Scrollview上滚动

来自分类Dev

在viewPager中的片段之间滑动时,选项卡高亮不会改变

来自分类Dev

如何在Java Android中为ViewPager滑动选项卡使用单个片段

来自分类Dev

使用ViewPager滑动视图将地图添加到片段中

来自分类Dev

滑动ViewPager中的选项卡时如何在片段之间发送数据

来自分类Dev

如何在Java Android中为ViewPager滑动选项卡使用单个片段

来自分类Dev

禁用父viewPager内的子viewViewr滑动

来自分类Dev

禁用父viewPager内的子viewviewr滑动

来自分类Dev

在UIPageViewController中禁用滑动

来自分类Dev

在ViewPager中回收片段

来自分类Dev

ViewPager片段中的CircularFloatingActionMenu

来自分类Dev

viewpager中的片段

来自分类Dev

ViewPager片段中的ListView

来自分类Dev

ViewPager片段中的CircularFloatingActionMenu

来自分类Dev

片段中的 Viewpager

来自分类Dev

viewpager 中的片段出错

来自分类Dev

ViewPager中的片段未触发协调器布局上的滚动

Related 相关文章

  1. 1

    需要禁用CollapsingToolbarLayout上某些片段的扩展

  2. 2

    使用ViewPager的CollapsingToolbarLayout中的片段不会向下滑动

  3. 3

    使用ViewPager的CollapsingToolbarLayout中的片段不会向下滑动

  4. 4

    如何在ViewPager中禁用特定页面滑动

  5. 5

    在片段级别与ViewPager一起应用了滑动手势,但禁用了默认滑动

  6. 6

    在Android上的ViewPager中替换当前片段

  7. 7

    在 RecyclerView 单击上替换 ViewPager 中的片段

  8. 8

    如何在某些活动中而不是在片段中禁用返回

  9. 9

    禁用在Android中打开导航抽屉的滑动手势

  10. 10

    滑动后刷新Android Viewpager片段

  11. 11

    滑动后刷新Android Viewpager片段

  12. 12

    片段内的 OnTouchListener 停止 Viewpager 滑动事件

  13. 13

    禁用在Scrollview上滚动

  14. 14

    在viewPager中的片段之间滑动时,选项卡高亮不会改变

  15. 15

    如何在Java Android中为ViewPager滑动选项卡使用单个片段

  16. 16

    使用ViewPager滑动视图将地图添加到片段中

  17. 17

    滑动ViewPager中的选项卡时如何在片段之间发送数据

  18. 18

    如何在Java Android中为ViewPager滑动选项卡使用单个片段

  19. 19

    禁用父viewPager内的子viewViewr滑动

  20. 20

    禁用父viewPager内的子viewviewr滑动

  21. 21

    在UIPageViewController中禁用滑动

  22. 22

    在ViewPager中回收片段

  23. 23

    ViewPager片段中的CircularFloatingActionMenu

  24. 24

    viewpager中的片段

  25. 25

    ViewPager片段中的ListView

  26. 26

    ViewPager片段中的CircularFloatingActionMenu

  27. 27

    片段中的 Viewpager

  28. 28

    viewpager 中的片段出错

  29. 29

    ViewPager中的片段未触发协调器布局上的滚动

热门标签

归档