在键盘弹出时获取键盘高度
- 继承 WidgetsBindingObserver 。
- 在 initState 内添加 WidgetsBinding.instance.addObserver(this); 。
- 在 dispose 内添加 WidgetsBinding.instance.removeObserver(this); 。
- 重写 didChangeMetrics,如下:
@override
void didChangeMetrics() {
super.didChangeMetrics();
// 键盘高度
final double viewInsetsBottom = EdgeInsets.fromWindowPadding(
WidgetsBinding.instance.window.viewInsets,
WidgetsBinding.instance.window.devicePixelRatio)
.bottom;
// 打印键盘高度
print(viewInsetsBottom);
setState(() {
bottom = viewInsetsBottom;
});
}
完整代码:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<StatefulWidget> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
double bottom = 0;
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
@override
void didChangeMetrics() {
super.didChangeMetrics();
// 键盘高度
final double viewInsetsBottom = EdgeInsets.fromWindowPadding(
WidgetsBinding.instance.window.viewInsets,
WidgetsBinding.instance.window.devicePixelRatio)
.bottom;
print(viewInsetsBottom);
setState(() {
bottom = viewInsetsBottom;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: Container(
color: Colors.yellow,
padding: EdgeInsets.only(bottom: bottom),
child: const TextField()),
);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
此处写了一个类方便使用,继承后重写 keyboardHeight 方法就行:
import 'dart:async';
import 'package:flutter/material.dart';
/// 继承此组件获取键盘高度
///
/// 重写 keyboardHeight 函数获取键盘高度
///
/// 某些机型会随着键盘弹出而接收到多次键盘高度事件,此方法已过滤。
mixin KeyboardHeight<T extends StatefulWidget>
on State<T>, WidgetsBindingObserver {
final WidgetsBinding _widgetsBinding = WidgetsBinding.instance;
late Timer timer;
@override
void initState() {
_widgetsBinding.addObserver(this);
super.initState();
}
@override
void didChangeMetrics() {
super.didChangeMetrics();
// 键盘高度
final viewInsets = EdgeInsets.fromWindowPadding(
WidgetsBinding.instance.window.viewInsets,
WidgetsBinding.instance.window.devicePixelRatio);
// 某些机型会随着键盘弹出而接收到多次键盘高度事件,在此延时32毫秒过滤出最终值。
try {
// 取消已有的延时任务,过滤出最终值。
timer.cancel();
} catch (_) {}
timer = Timer(const Duration(milliseconds: 32), () {
keyboardHeight(viewInsets.bottom);
});
}
// 重写此事件获取键盘高度
void keyboardHeight(double height) {}
@override
void dispose() {
_widgetsBinding.removeObserver(this);
super.dispose();
}
}
使用方法:
class _ChatPageState extends State<ChatPage> with WidgetsBindingObserver, KeyboardHeight {
@override
keyboardHeight(double height) {
// 高度
}
}