目录
注: 此思路由国外一大神提出,附上他的 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);
