软键盘与PopupWindow的冲突

问题一:设置activity的SoftInputMode无效

在需求中,PopupWindow的布局需要EditText的layout居于底部,软键盘弹出时候要把EditText往上顶,但是布局整体不会往上走,然后大家都知道使用adjustResize属性,但是这个属于要对应到相应的Window上才会生效的。

错误且无效代码
    //设置activity的属性
    activity.getWindow().getAttributes().softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
    ////给Activity的window窗口设置软键盘展示属性
    activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    

正确且有效的代码
        mPopupWindow.setFocusable(true);
        mPopupWindow.setOutsideTouchable(false);
        mPopupWindow.setContentView(mContentView);
        mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
        //给PopupWindow的window窗口设置软键盘展示属性
        mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        mPopupWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, 0, 0);
知识点补充

在一个Activity上如何统计有多少个Window,大家都知道View的层级关系是Window -> DecorView,这个在Android艺术开发探索中有详细讲解,大家不明白的可以去查下。回归正题,如何统计一个Activity上的Window数量。

总数: window_all_number = iphoneWindow + 全部的PopupWindow的Window + 全部的Dialog的Window。

所以说各自的Window会管理各自的布局变化,上面我是想修改PopupWindow布局的ajustResize属性,但是却去修改了activity上的ajustResize属性,很显然这样子做popupWindow上是没有ajustResize属性,所以自然达不到要求的效果。

问题二:设置PopupWindow的ajustResize属性后,EditText的Layout一直在底部,不跟随软键盘的弹出往上顶,就是软键盘挡住了PopupWindow的底部布局

失败尝试方法1

因为我的activity的SoftInputMode属性是SOFT_INPUT_ADJUST_NOTHING,然后我强行在PopupWindow显示时候设置成SOFT_INPUT_ADJUST_RESIZE

    if (activity != null) {
        activity.getWindow().getAttributes().softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    }

suprice MDF:失败是兵家常事,要学会分析原因,这里是因为PopupWindow和Activity的window不同,设置这个属性不会影响到PopupWindow的布局属性的,所以失败很正常。


失败尝试方法2

改变PopupWindow的初始化

    //这种初始化需要后面制定宽高,我就替换成下面的代码
    mPopupWindow = new PopupWindow(v, -2, -1);
    
    //修改后
    mPopupWindow = new PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

失败原因:PopupWindow初始化与设置ajustResize属性没太大关系,设置ajustResize属性是当软键盘弹出时候,系统会缩小当前布局的高度,从而适应软键盘的弹出。在失败两次之后,我觉得把目光锁定在了PopupWindow的宽高设置上。


问题二的解决办法

上面也分析说了将目光锁定在PopupWindow的宽高设置上,先看下代码中的宽高如何设置的。
    mPopupWindow.setWidth(WindowManagerHelper.getDisplayWidth(mContentView.getContext()));
    mPopupWindow.setHeight(WindowManagerHelper.getDisplayHeight(mContentView.getContext()));

代码中的mContentView.getContext是属于Activity的Context,因为你的mContentView是通过LayoutInflater.from(context).inflate去生成的。所以你可以想下,当你的PopupWindow的ajustResize起作用时候,是不是当前布局改变由Window控制,但是上面代码这样设置后,是将PopupWindow的大小改变选择权交给了Activity的Window去控制,所以当你设置ajustResize后,软键盘弹出,布局大小没有改变,因为PopupWindow的Window虽然接收通知,但是却改变大小权利不在它手上。

如何修改
  • 改变PopupWindow初始化值
  • 将PopupWindow的大小改变权限交换给PopupWindow的Window

    //错误版本
    mPopupWindow = new PopupWindow(v, -2, -1);
    
    mPopupWindow.setWidth(WindowManagerHelper.getDisplayWidth(mContentView.getContext()));
    mPopupWindow.setHeight(WindowManagerHelper.getDisplayHeight(mContentView.getContext()));
    
    //修改版本代码
    mPopupWindow = new PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    
    //上面是跟随父布局大小,就不需要手动设置宽高值
    

总结

View的层级管理和View的测量,布局,绘制过程都是android最有趣的地方,希望与大家一起加油,在项目中学习和成长。上面可能会存在理解不够深入的地方,希望大家可以指出让我完善自己的知识面。fighting……

你可能感兴趣的:(软键盘与PopupWindow的冲突)