PopupWindow 跟我们的 Activity 不一样,因为我们在构造 PW 的时候往往不是继承来的,而是 new 出来的。所以不能使用重写 PW 的 onKeyDown() 之类的方法来截获键盘事件。网上很多方案经验证无法解决。我的解决方案如下
对最外层布局view.getViewTreeObserver().addOnGlobalLayoutListener(mLayoutChangeListener);
private ViewTreeObserver.OnGlobalLayoutListener mLayoutChangeListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//当键盘弹出隐藏的时候会 调用此方法
UtilsLog.d(TAG, "onGlobalLayout");
Rect r = new Rect();
getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
int statusBarHeight=MyUtils.getStatusBarHeight(mContext);
int heightDifference = ScreenUtils.screenHeight - r.bottom - statusBarHeight;
UtilsLog.d(TAG, "Keyboard Size: " + heightDifference + " screenHeight=" + ScreenUtils.screenHeight + " bottom=" + r.bottom + " "
+ " h=" + ScreenUtils.screenHeight + " statusBarHeight=" + statusBarHeight);
if(heightDifference>ScreenUtils.screenHeight/4) {
softInputValue=heightDifference;
}else{
if(softInputValue>0){
softInputValue=0;
if(popWindow!=null){
popWindow.dismiss();
UtilsLog.d(TAG, "onGlobalLayout dismiss" );
}
}
}
}
};
监听键盘的变化并保存,按返回键会走else分支,重置value并让PopupWindow消失,前值和后值的比较,这也是键盘弹起和消失的数值变化规律,从而避免按两次返回键
@Override
public void onDestroy() {
super.onDestroy();
if (Build.VERSION.SDK_INT >= 16) {
view.getViewTreeObserver().removeOnGlobalLayoutListener(mLayoutChangeListener);
} else {
view.getViewTreeObserver().removeGlobalOnLayoutListener(mLayoutChangeListener);
}
}
最后取消注册避免内存泄漏