/** * 是否传播按键事件。 在软键盘隐藏的时候记录系统时间,当点击手机按键的时候,再取一次系统时间,比较两次时间差 * 如果差值小于某一值(一个经验值,目前是100毫秒)就认为是在很短时间内响应了手机按键,此时 认为手机按键的操作是关闭软键盘,则不需要再传播事件,如果大于该值,则认为是需要执行手机 * 按键事件,则需要传播以便执行js * * <p>为什么要根据临界值去判断? 因为,在软键盘弹出后,我们点击返回键,需要经过一下流程: 软键盘关闭->软键盘将返回事件继续传播->xFace响应返回键事件 * 那么这一段事件是系统在处理,所以关闭软键盘到响应返回键这个时间很短 * * <p>如果点击屏幕空白处将软键盘关闭,再点返回键,在这一流程中,由于是人为的关闭了软键盘和人为 的点击了返回键,所以这个时间比起系统自己来处理要长得多。 * 所以才根据临界时间来判断是否是关闭软键盘的操作。 * * @return true 传播 false 不传播 */ public boolean isPropagateEvent() { long currentSystime = 0; currentSystime = System.currentTimeMillis(); XLog.d( CLASS_NAME, "The time difference is : " + (currentSystime - mCurrentSysTimeWhenSoftKeyboardHidden)); // 计算两次时间差,小于临界值就认为,本次事件是关闭软键盘,那么就不传播事件了 if (currentSystime - mCurrentSysTimeWhenSoftKeyboardHidden < CRITICAL) { return false; } return true; }
@Override /** * 监听measurement事件,根据view的高度判断软键盘是否弹出 * * @param widthMeasureSpec * @param heightMeasureSpec */ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width, height; height = MeasureSpec.getSize(heightMeasureSpec); width = MeasureSpec.getSize(widthMeasureSpec); // 初始状态 if (mOldHeight == 0 || mOldHeight == height) { XLog.d(CLASS_NAME, "Ignore this event"); } // 转屏 else if (mScreenHeight == width) { int tmp_var = mScreenHeight; mScreenHeight = mScreenWidth; mScreenWidth = tmp_var; XLog.i(CLASS_NAME, "Orientation Change"); } // 软键盘隐藏了 else if (height > mOldHeight) { XLog.i(CLASS_NAME, "Soft Keyboard Hidden"); mCurrentSysTimeWhenSoftKeyboardHidden = System.currentTimeMillis(); } // 软键盘弹出 else if (height < mOldHeight) { XLog.i(CLASS_NAME, "Soft Keyboard Shown"); } mOldHeight = height; mOldWidth = width; }