安卓获取输入法高度与ViewTreeObserver讲解

 目录

  • 注: 此思路由国外一大神提出,附上他的 Github ;

    清单

    这里有两个文件:

    • interface KeyboardHeightObserver
    • class KeyboardHeightProvider

    前一个用在待观测页面的作为回调函数, 后面是主要的方法所在的类了。

    开始

    文章后面会附上源码,引入这两个文件后,在要获取输入法高度的页面,首先实现接口KeyboardHeightObserver,即第一个文件,并重写里面的方法;

    然后再定义变量 KeyboardHeightProvider keyboardHeightProvider;
    实例化

         /**      * Construct a new KeyboardHeightProvider      *      * @param activity The parent activity      * @param layoutId   R.layout.*      */        // 以上为构造函数的相关注释,当然这里是我修改的,这样可以同时支持观测多个页面        keyboardHeightProvider = new KeyboardHeightProvider(this, R.layout.activity_chat);         new Handler().post(new Runnable() {             @Override             public void run() {                 keyboardHeightProvider.start();             }         }); 

    这时还要在onStart()函数里面加上 keyboardHeightProvider.setKeyboardHeightObserver(this); 即:

        @Override     public void onStart() {         super.onStart();         // 这里使用了刚才实现的接口         keyboardHeightProvider.setKeyboardHeightObserver(this);     } 

    考虑更全的话, 还可以加上以下语句:

        @Override     public void onPause() {         super.onPause();         keyboardHeightProvider.setKeyboardHeightObserver(null);     }      @Override     public void onDestroy() {         super.onDestroy();         keyboardHeightProvider.close();     }       

    这样一来,在回调函数 onKeyboardHeightChanged里面就回收到回调结果了,大功告成!

    ViewTreeObserver讲解

    这里就结合上面输入法的例子,讲讲ViewTreeObserver。

    获取输入法高度原理

    思路

    在要获取输入法高度的页面,创建一个看不见的弹窗,即宽为0,高为全屏,并为弹窗设置全局布局监听器。当布局有变化,比如有输入法弹窗出现或消失时, 监听器回调函数就会被调用。而其中的关键就是当输入法弹出时, 它会把之前我们创建的那个看不见的弹窗往上挤, 这样我们创建的那个弹窗的位置就变化了,只要获取它底部高度的变化值就可以间接的获取输入法的高度了。

    实现

    首先创建类KeyboardHeightProvider, 继承自PopupWindow;

    然后构造器内完成相关初始化:

             super(activity);         this.activity = activity;         LayoutInflater inflator = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);         this.popupView = inflator.inflate(layoutId, null, false);         setContentView(popupView);          setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);         setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);          parentView = activity.findViewById(android.R.id.content);          // 设置宽高         setWidth(0);        
                        
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信