Flutter中FloatingActionButton.extended键盘弹出时位置错位问题
问题现象
Flutter开发过程中使用FloatingActionButton.extended组件时出现显示异常:当键盘弹出时,FAB会出现在屏幕中间位置,并未停靠在键盘上方。目前公开的相关讨论方案均不适配当前业务场景。
相关业务代码
Widget build(BuildContext context) { final isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0; return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( iconTheme: const IconThemeData(color: Colors.black), backgroundColor: Colors.transparent, elevation: 0, actions: [ IconButton( onPressed: () async { await Databahelper.instance.deleteNote(widget.note!.id!); Navigator.of(context).push( MaterialPageRoute(builder: (_) => const StickyNote())); }, icon: const Icon(Icons.delete)), ], ), body: Padding( padding: const EdgeInsets.all(10.0), child: Column( children: [ const SizedBox(height: 8), TextField( maxLines: 1, controller: titleController, decoration: const InputDecoration( label: Text( 'Title', style: TextStyle(fontSize: 20), ), ), ), const SizedBox( height: 30, ), Expanded( child: TextField( keyboardType: TextInputType.multiline, controller: descController, maxLines: null, decoration: const InputDecoration( border: InputBorder.none, contentPadding: EdgeInsets.all(10), hintText: "Enter Your Text...", hintStyle: TextStyle( fontSize: 12, color: Colors.purple, fontStyle: FontStyle.italic, ), ), ), ) ], ), ), bottomNavigationBar: Visibility( visible: !isKeyboard, child: BottomAppBar( elevation: 4, color: backgroundColor, child: SizedBox( height: 50, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( onPressed: () {}, icon: const Icon(Icons.add_box_outlined)), const Text('July 2050'), IconButton( onPressed: () {}, icon: const Icon(Icons.more_vert)), ], ), ), ), ), floatingActionButton: FloatingActionButton.extended( onPressed: () { setState(() { title = titleController.text; description = descController.text; }); NotedB notelocal = NotedB(title: title, description: description); addNote(notelocal); Navigator.push( context, MaterialPageRoute(builder: (_) => const StickyNote())); }, label: const Text('Save note'), icon: const Icon(Icons.note_add_outlined), )); }
异常显示截图

解决方案
问题根源:你设置了键盘弹出时隐藏高度为50的BottomAppBar,但Scaffold默认计算FAB位置时会预留BottomAppBar的高度,导致键盘弹出时FAB多了无效的底部间距,错位到屏幕中间。按以下两步修改即可:
- 给Scaffold显式添加停靠位置属性,指定FAB的默认停靠规则
- 给FAB加动态底部padding,适配BottomAppBar显示/隐藏两种状态
修改后的核心代码片段如下:
return Scaffold( backgroundColor: backgroundColor, // 显式指定页面自动适配键盘高度 resizeToAvoidBottomInset: true, // 指定FAB的默认停靠位置为底部居中浮动 floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, appBar: /* 原有代码保持不变 */, body: /* 原有代码保持不变 */, bottomNavigationBar: /* 原有代码保持不变 */, floatingActionButton: Padding( // 键盘弹出时BottomAppBar隐藏,取消预留的50高度间距 padding: EdgeInsets.only(bottom: isKeyboard ? 0 : 50), child: FloatingActionButton.extended( // 原有FAB属性保持不变 onPressed: () { setState(() { title = titleController.text; description = descController.text; }); NotedB notelocal = NotedB(title: title, description: description); addNote(notelocal); Navigator.push( context, MaterialPageRoute(builder: (_) => const StickyNote())); }, label: const Text('Save note'), icon: const Icon(Icons.note_add_outlined), ), ), );
内容的提问来源于stack exchange,提问作者user17310705
相关产品推荐
相关产品推荐

