Flutter 中监听键盘弹出&键盘高度
2025-04-29 本文已影响0人
黑炭长
在移动端的开发中,监听键盘弹起 & 键盘高度是比较常用的功能,特别是聊天页面,那么如何优雅的弹出输入框呢,这里需要分情况处理
1、输入框在页面底部的(经典的聊天窗口)
这种情况相对简单一些直接使用Scaffold自带的弹出键盘的效果 会自动的将输入框的视图置于键盘顶部,我们无需过多处理
Scaffold(
body:Column(
children: [
Expanded(
child:ListView.builder(
itemBuilder: (ctx, i) {
return Container();
}
),
),
SafeArea(
top: false,
child: textInputContainer(),
),
],
),
)
类似上述的结构 点击输入框textInputContainer 系统自动处理
2、我们说特殊情况的输入框
我们这边有一个需求 输入框 不在底部 距离底部120的地方,这个时候 还是用1中的方法,会发现 输入框底部始终有一个120的高度,这就要说一下Scaffold 自动弹起键盘的机制了,实际上是 将整个视图高度缩短了一个键盘的高度,这种情况显然就不能满足我们的需求了,我们应该怎么处理 直接上代码
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '键盘适应示例',
home: KeyboardAwarePage(),
);
}
}
class KeyboardAwarePage extends StatefulWidget {
@override
_KeyboardAwarePageState createState() => _KeyboardAwarePageState();
}
class _KeyboardAwarePageState extends State<KeyboardAwarePage> with WidgetsBindingObserver {
double _keyboardHeight = 0;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this); // 监听窗口变化
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeMetrics() {
final bottomInset = WidgetsBinding.instance.window.viewInsets.bottom;
setState(() {
_keyboardHeight = bottomInset / MediaQuery.of(context).devicePixelRatio;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('键盘监听示例')),
resizeToAvoidBottomInset: false,
body: Stack(
children: [
// 主体内容
Positioned.fill(
child: Center(child: Text("主内容区域")),
),
// 输入框
Positioned(
left: 0,
right: 0,
bottom: _keyboardHeight > 0 ? _keyboardHeight : 80,
child: Container(
color: Colors.white,
padding: EdgeInsets.all(12),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "请输入内容",
),
),
),
),
],
),
);
}
}
设置 resizeToAvoidBottomInset: false 不使用Scaffold的该功能 自己维度底部偏移
3,键盘的监听
- 监听单个输入框
FocusNode inputFocus = FocusNode();
/// 监听键盘
inputFocus.addListener(() {
hasFocus.value = inputFocus.hasFocus;
});
TextField(
scrollPadding: EdgeInsets.zero,
focusNode: controller.inputFocus,
)
- 使用插件 keyboard_visibility
具体使用方法 可查看官方文档