Flutter中实现键盘弹出时隐藏miniCenterDocked类型FloatingActionButton
针对键盘弹出时FloatingActionButton上浮的问题,提供两种可行方案:
方案一:键盘弹出时隐藏FloatingActionButton
通过监听键盘的显示/隐藏状态,动态控制FAB的显示与否。
修改后的完整代码
import 'package:ecommerce/pages/all_products.dart'; import 'package:flutter/material.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> with WidgetsBindingObserver { int currentTab = 2; final List<Widget> screens = [ const Text('Profile'), const Text('Search'), const AllProductsPage(), const Text('Favorites'), const Text('Cart'), ]; final PageStorageBucket bucket = PageStorageBucket(); Widget currentScreen = const AllProductsPage(); bool _isKeyboardVisible = false; // 标记键盘是否处于显示状态 @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeMetrics() { super.didChangeMetrics(); final bottomInset = WidgetsBinding.instance.window.viewInsets.bottom; setState(() { _isKeyboardVisible = bottomInset > 0; }); } @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( extendBody: true, body: PageStorage( bucket: bucket, child: currentScreen, ), // 根据键盘状态控制FAB显示/隐藏 floatingActionButton: _isKeyboardVisible ? null : FloatingActionButton( onPressed: () { _updateScreen(2, const AllProductsPage()); }, child: Icon( Icons.home, color: _getColor(2), ), ), floatingActionButtonLocation: FloatingActionButtonLocation.miniCenterDocked, bottomNavigationBar: BottomAppBar( shape: const CircularNotchedRectangle(), notchMargin: 12, child: SizedBox( height: 70, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ _createItemBar(Icons.person, 0, 'Profile'), _createItemBar(Icons.search, 1, 'Search'), ], ), Row( children: [ _createItemBar(Icons.favorite, 3, 'Favorites'), _createItemBar(Icons.shopping_cart, 4, 'Cart'), ], ), ], ), ), ), ), ); } Widget _createItemBar(IconData icon, int index, String text) { return MaterialButton( splashColor: Colors.transparent, minWidth: 40, onPressed: () { _updateScreen(index, screens[index]); }, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: _getColor(index)), Text( text, style: TextStyle( color: _getColor(index), ), ), ], ), ); } Color _getColor(int index) { return currentTab == index ? Colors.green : Colors.grey; } void _updateScreen(int index, Widget screen) { setState(() { currentScreen = screen; currentTab = index; }); } }
方案二:键盘弹出时固定FloatingActionButton位置
禁止Scaffold随键盘调整布局,同时确保TextField不被键盘遮挡。
步骤1:修改HomePage的Scaffold配置
@override Widget build(BuildContext context) { return SafeArea( child: Scaffold( extendBody: true, resizeToAvoidBottomInset: false, // 禁止Scaffold随键盘调整布局 body: PageStorage( bucket: bucket, child: currentScreen, ), floatingActionButton: FloatingActionButton( onPressed: () { _updateScreen(2, const AllProductsPage()); }, child: Icon( Icons.home, color: _getColor(2), ), ), floatingActionButtonLocation: FloatingActionButtonLocation.miniCenterDocked, bottomNavigationBar: BottomAppBar( shape: const CircularNotchedRectangle(), notchMargin: 12, child: SizedBox( height: 70, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ _createItemBar(Icons.person, 0, 'Profile'), _createItemBar(Icons.search, 1, 'Search'), ], ), Row( children: [ _createItemBar(Icons.favorite, 3, 'Favorites'), _createItemBar(Icons.shopping_cart, 4, 'Cart'), ], ), ], ), ), ), ), ); }
步骤2:调整包含TextField的页面(如AllProductsPage)
class AllProductsPage extends StatelessWidget { const AllProductsPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return SingleChildScrollView( child: Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom, ), child: Column( children: [ // 页面其他内容 const TextField( decoration: InputDecoration(hintText: "输入搜索内容"), ), // 页面其他内容 ], ), ), ); } }
内容的提问来源于stack exchange,提问作者KIRO EMAD
相关产品推荐
相关产品推荐

