我们知道在Flutter中获取键盘高度可以通过向WidgetsBinding注册监听,当键盘弹出或消失时会回调didChangeMetrics方法。需要注意的是,在Flutter3新增IOS键盘动画后,IOS会和Android一样回调didChangeMetrics多次,并且每次回调中MediaQueryData.fromWindow(window).viewInsets.bottom的值都是此时键盘冒出来的高度,即键盘实时高度。如果我们想获取键盘的完整高度,只需要一直取和上次相比的最大值,然后保存下来就可以了。
/// Flutter3
/// 堆代码 duidaima.com
/// 获取键盘高度
@override
void didChangeMetrics() {
final bottom = MediaQueryData.fromWindow(window).viewInsets.bottom;
// 键盘存在中间态,回调是键盘冒出来的高度
keyboardHeight = max(keyboardHeight, bottom);
if (bottom == 0) {
isKeyboardShow = false;
} else if (bottom == keyboardHeight || keyboardHeight == 0) {
isKeyboardShow = true;
} else {
isKeyboardShow = null;
}
// 键盘完全收起或展开再刷新页面
if (isKeyboardShow != null && _preKeyboardShow != isKeyboardShow) {
_keyboardStateNotifier.notifyListeners();
}
if (bottom < keyboardHeight) {
_sp?.setDouble(KEYBOARD_MAX_HEIGHT, keyboardHeight);
}
}
/// Flutter3之前,获取键盘高度
@override
void didChangeMetrics() {
final bottom = MediaQueryData.fromWindow(window).viewInsets.bottom;
/// ios点击键盘表情时,键盘高度会增加,后面点拼音后也回不到这个高度了
if (Platform.isIOS) {
/// ios键盘有两种高度,但不存在中间态,回调就是键盘高度
isKeyboardShow = bottom > 0;
if (isKeyboardShow) {
keyboardHeight = bottom;
}
} else {
/// Android键盘存在中间态,回调是键盘冒出来的高度
keyboardHeight = max(keyboardHeight, bottom);
if (bottom == 0) {
isKeyboardShow = false;
} else if (bottom == keyboardHeight || keyboardHeight == 0) {
isKeyboardShow = true;
} else {
isKeyboardShow = null;
}
}
// 键盘完全收起或展开再刷新页面
if (isKeyboardShow != null && _preKeyboardShow != isKeyboardShow) {
_keyboardStateNotifier.notifyListeners();
}
if (bottom < keyboardHeight) {
_sp?.setDouble(KEYBOARD_MAX_HEIGHT, keyboardHeight);
}
}
例如我们想在键盘上做一个输入框,只需要给输入框底部添加一个和键盘实时高度相同的Padding,就能做到像Scaffold#bottomSheet一样跟随键盘动画的效果了。