欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

软键盘与PopupWindow的冲突

程序员文章站 2022-03-02 14:36:31
...

问题一:设置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……