问题:项目当中,ViewPager里面放了3个View,从第1个切换到第2个是有限制条件的,比如,必须填写完某些信息。 但是HTC G11 自带键盘下方多了上下左右4个切换的键,如图:
这个时候按会切换Viewpager所嵌套的几个View。这个问题让我纠结了几天,当时是小白(现在看起来问题很简单了)不知道Android事件分发机制,若要学习Android的事件分发机制建议看 Android源码分析-点击事件派发机制
问题解决思路:手势触发系统键盘的左右滑动事件,首先会传递到Activity的dispatchTouchEvent事件,所以在其里面捕获到键盘的左右事件,返回false即可。因为返回false代表不进行处理该事件。看下它的源码吧,特别是英文注释
/** * Called to process touch screen events. You can override this to * intercept all touch screen events before they are dispatched to the * window. Be sure to call this implementation for touch screen events * that should be handled normally. * * @param ev The touch screen event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { //这个函数其实是个空函数,啥也没干,如果你没重写的话,不用关心 onUserInteraction(); } //这里事件开始交给Activity所附属的Window进行派发,如果返回true,整个事件循环就结束了 //返回false意味着事件没人处理,所有人的onTouchEvent都返回了false,那么Activity就要来做最后的收场。 if (getWindow().superDispatchTouchEvent(ev)) { return true; } //这里,Activity来收场了,Activity的onTouchEvent被调用 return onTouchEvent(ev); }
问题修复: 在Activity中屏蔽键盘的上下左右
@Override public boolean dispatchKeyEvent(KeyEvent event) { // TODO Auto-generated method stub switch (event.getKeyCode()) { case KeyEvent.KEYCODE_DPAD_DOWN://按向下键 LogUtil.e(PublishCarActivity.class, "向下"); break; case KeyEvent.KEYCODE_DPAD_UP: LogUtil.e(PublishCarActivity.class, "向上"); break; case KeyEvent.KEYCODE_DPAD_LEFT: LogUtil.e(PublishCarActivity.class, "向左"); return false; case KeyEvent.KEYCODE_DPAD_RIGHT: LogUtil.e(PublishCarActivity.class, "向右"); return false; } return super.dispatchKeyEvent(event); }
所以,大家一定要认真学习Android 内部的事件分发机制,这样遇到问题才会“微微一笑,根本不鸟”