要实现禁止ViewPager的滑动,要怎么实现呢?
第一想到就是继承ViewPager,重写ViewPager的TouchEvent事件,在TouchEvent的事件中不作任何直接return true即可。
但是这样就可以了吗?NO
你可以试一下在Viewpager中的一个输入框,弹出软键盘,然后再软键盘上向左滑动或者向右滑动,此时你会发现当光标滑到输入框的最左边或者最后边时,ViewPager依然会滑动,why?(此种情况下,在有的手机很容易复现,有的手机不容易,华为和夏新的手机容易复现,HTC的不容易复现)
根据遇到的问题,是由于软键盘的滑动引起,既然知道原因,那么我们直接看ViewPaer中的dispatchKeyEvent方法:
@Override public boolean dispatchKeyEvent(KeyEvent event) { // Let the focused view and/or our descendants get the key first return super.dispatchKeyEvent(event) || executeKeyEvent(event); }
接着我们继续看executeKeyEvent方法:public boolean executeKeyEvent(KeyEvent event) { boolean handled = false; if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (event.getKeyCode()) { case KeyEvent.KEYCODE_DPAD_LEFT: handled = arrowScroll(FOCUS_LEFT); break; case KeyEvent.KEYCODE_DPAD_RIGHT: handled = arrowScroll(FOCUS_RIGHT); break; case KeyEvent.KEYCODE_TAB: if (Build.VERSION.SDK_INT >= 11) { // The focus finder had a bug handling FOCUS_FORWARD and FOCUS_BACKWARD // before Android 3.0. Ignore the tab key on those devices. if (KeyEventCompat.hasNoModifiers(event)) { handled = arrowScroll(FOCUS_FORWARD); } else if (KeyEventCompat.hasModifiers(event, KeyEvent.META_SHIFT_ON)) { handled = arrowScroll(FOCUS_BACKWARD); } } break; } } return handled; }executeKeyEvent方法中会根据是否是KEYCODE_DPAD_LEFT
KEYCODE_DPAD_RIGHT
KEYCODE_TAB
来调用arrowScroll的方法,arrowScroll方法顾名思义就是是否允许滑动,它的参数就是向前、向后滑动。好,我们继续往下看看arrowScroll方法:此处不贴源码了,最终会在arrowScroll中调用pageLeft和pageRight方法,我们看下pageLeft的方法:boolean pageLeft() { if (mCurItem > 0) { setCurrentItem(mCurItem-1, true); return true; } return false; }此处调用setCurrentItem来跳转页面了。
综合上面的分析,我们知道了根本原因是executeKeyEvent引起的,那么我们可以直接重写executeKeyEvent方法,在executeKeyEvent方法中直接返回false即可