Flutter中Bottom Overflowed By Infinity Pixels问题求助
问题描述
在Flutter应用底部添加导航栏后,出现「Bottom Overflowed By Infinity Pixels」错误。尝试过用scroll view、mainAxisAlignment、Expanded等组件包裹相关Widget,也试过多种解决方案,包括用Expanded包裹Container、SafeArea,用SingleChildScrollView包裹Widget及两者结合,但均未解决问题。
原HomePage代码
import 'package:date_picker_timeline/date_picker_timeline.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:get/get.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:ride/controllers/task_controller.dart'; import 'package:ride/services/theme_services.dart'; import 'package:ride/ui/add_task_bar.dart'; import 'package:ride/ui/theme.dart'; import 'package:ride/ui/widgets/button.dart'; import 'package:ride/ui/widgets/task_tile.dart'; import '../models/task.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { final int _selectedIndex = 0; static const List<Widget> _widgetOptions = <Widget>[ AddTaskPage(), ]; DateTime _selectedDate = DateTime.now(); final _taskController = Get.put(TaskController()); @override Widget build(BuildContext context) { return Scaffold( appBar: _appbar(), backgroundColor: context.theme.colorScheme.background, body: Column(children: [ _addTaskBar(), _addDateBar(), _widgetOptions.elementAt(_selectedIndex), _showTasks(), ]), ); } _showTasks() { return Expanded( child: Obx(() { return ListView.builder( itemCount: _taskController.taskList.length, itemBuilder: (_, index) { Task task = _taskController.taskList[index]; //print(task.toJson()); if (task.date == DateFormat.yMd().format(_selectedDate)) { return AnimationConfiguration.staggeredList( position: index, child: SlideAnimation( child: FadeInAnimation( child: Row( children: [ GestureDetector( onTap: () { _showBottomSheet(context, task); }, child: TaskTile(task), ) ], )))); } else { return Container(); } }); }), ); } _showBottomSheet(BuildContext context, Task task) { Get.bottomSheet( Container( padding: const EdgeInsets.only(top: 4), height: task.isCompleted == 1 ? MediaQuery.of(context).size.height * 0.24 : MediaQuery.of(context).size.height * 0.32, color: Get.isDarkMode ? Colors.grey[850] : Colors.white, child: Column(children: [ Container( height: 6, width: 120, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.grey[600]), ), const Spacer(), task.isCompleted == 1 ? Container() : _bottomSheetButton( label: "Join", onTap: () { _taskController.markTaskCompleted(task.id!); Get.back(); }, clr: primaryClr, context: context), _bottomSheetButton( label: "Delete", onTap: () { _taskController.delete(task); Get.back(); }, clr: Colors.red[400]!, context: context), const SizedBox( height: 20, ), _bottomSheetButton( label: "Close", onTap: () { Get.back(); }, clr: Colors.red[400]!, isClose: true, context: context), const SizedBox(height: 10), ]), ), ); } _bottomSheetButton({ required String label, required Function()? onTap, required Color clr, bool isClose = false, required BuildContext context, }) { return GestureDetector( onTap: onTap, child: Container( margin: const EdgeInsets.symmetric(vertical: 4), height: 55, width: MediaQuery.of(context).size.width * 0.9, decoration: BoxDecoration( border: Border.all( width: 2, color: isClose == true ? Get.isDarkMode ? Colors.grey[600]! : Colors.grey[400]! : clr), borderRadius: BorderRadius.circular(20), color: isClose == true ? Colors.transparent : clr, ), child: Center( child: Text( label, style: isClose ? titleStyle : titleStyle.copyWith(color: Colors.white), )), ), ); } _addDateBar() { return Container( margin: const EdgeInsets.only( top: 20, left: 20, ), child: DatePicker( DateTime.now(), height: 100, width: 80, initialSelectedDate: DateTime.now(), selectionColor: primaryClr, selectedTextColor: Colors.white, dateTextStyle: GoogleFonts.lato( textStyle: const TextStyle( fontSize: 20, fontWeight: FontWeight.w600, color: Colors.grey), ), dayTextStyle: GoogleFonts.lato( textStyle: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.grey), ), monthTextStyle: GoogleFonts.lato( textStyle: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: Colors.grey), ), onDateChange: (date) { setState(() { _selectedDate = date; }); }, ), ); } _addTaskBar() { return Container( margin: const EdgeInsets.only(right: 20, top: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( margin: const EdgeInsets.symmetric(horizontal: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( DateFormat.yMMMMd().format(DateTime.now()), style: subHeadingStyle, ), Text( 'Today', style: headingStyle, ) ], ), ), MyButton( label: "+ Add", onTap: () async { await Get.to(const AddTaskPage()); _taskController.getTasks(); }) ], ), ); } _appbar() { return AppBar( elevation: 0, backgroundColor: context.theme.colorScheme.background, leading: GestureDetector( onTap: () { ThemeService().switchTheme(); }, child: Icon( Get.isDarkMode ? Icons.wb_sunny_outlined : Icons.dark_mode_outlined, size: 30, color: Get.isDarkMode ? Colors.white : Colors.black), ), actions: [ Icon(Icons.person_outline, size: 30, color: Get.isDarkMode ? Colors.white : Colors.black), const SizedBox( width: 15, ) ]); } }
原main.dart代码
import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:get/get_navigation/src/root/get_material_app.dart'; import 'package:ride/login/login.dart'; import 'package:ride/services/theme_services.dart'; import 'package:ride/ui/home_page.dart'; import 'package:ride/ui/theme.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final prefs = await SharedPreferences.getInstance(); final isLoggedIn = prefs.getBool('isLoggedIn') ?? false; await Firebase.initializeApp(); WidgetsFlutterBinding.ensureInitialized(); runApp(MyApp(isLoggedIn: isLoggedIn)); } class MyApp extends StatelessWidget { final bool isLoggedIn; const MyApp({super.key, required this.isLoggedIn}); //Root of Application @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: Themes.light, darkTheme: Themes.dark, themeMode: ThemeService().theme, home: isLoggedIn ? const HomePage() : LogIn()); } }
解决方案
问题根源在于HomePage的body中,Column直接包含了_widgetOptions.elementAt(_selectedIndex)(即AddTaskPage),而AddTaskPage作为独立页面组件,本身未限制高度,加上Column中其他组件的高度,导致整体内容超出屏幕高度;同时Expanded仅能处理单个子组件的剩余空间分配,无法解决多个未限制高度组件的溢出问题。
具体修复步骤:
- 移除
Column中多余的_widgetOptions.elementAt(_selectedIndex),AddTaskPage是通过按钮跳转的页面,无需直接嵌入主页布局。 - 若需要底部导航栏,在
Scaffold中添加bottomNavigationBar属性,而非将页面组件嵌入body的Column。 - 确保body的
Column中,仅_showTasks()用Expanded包裹,让其占用剩余屏幕空间,其他组件为固定高度,避免无限高度溢出。
修改后的HomePage代码
import 'package:date_picker_timeline/date_picker_timeline.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:get/get.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:ride/controllers/task_controller.dart'; import 'package:ride/services/theme_services.dart'; import 'package:ride/ui/add_task_bar.dart'; import 'package:ride/ui/theme.dart'; import 'package:ride/ui/widgets/button.dart'; import 'package:ride/ui/widgets/task_tile.dart'; import '../models/task.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { DateTime _selectedDate = DateTime.now(); final _taskController = Get.put(TaskController()); @override Widget build(BuildContext context) { return Scaffold( appBar: _appbar(), backgroundColor: context.theme.colorScheme.background, // 添加底部导航栏示例 bottomNavigationBar: BottomNavigationBar( items: const [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '主页'), BottomNavigationBarItem(icon: Icon(Icons.add), label: '添加任务'), ], currentIndex: 0, onTap: (index) { if (index == 1) { Get.to(const AddTaskPage()); } }, ), body: Column( children: [ _addTaskBar(), _addDateBar(), _showTasks(), ], ), ); } _showTasks() { return Expanded( child: Obx(() { return ListView.builder( itemCount: _taskController.taskList.length, itemBuilder: (_, index) { Task task = _taskController.taskList[index]; if (task.date == DateFormat.yMd().format(_selectedDate)) { return AnimationConfiguration.staggeredList( position: index, child: SlideAnimation( child: FadeInAnimation( child: Row( children: [ GestureDetector( onTap: () { _showBottomSheet(context, task); }, child: TaskTile(task), ) ], )))); } else { return Container(); } }); }), ); } _showBottomSheet(BuildContext context, Task task) { Get.bottomSheet( Container( padding: const EdgeInsets.only(top: 4), height: task.isCompleted == 1 ? MediaQuery.of(context).size.height * 0.24 : MediaQuery.of(context).size.height * 0.32, color: Get.isDarkMode ? Colors.grey[850] : Colors.white, child: Column(children: [ Container( height: 6, width: 120, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.grey[600]), ), const Spacer(), task.isCompleted == 1 ? Container() : _bottomSheetButton( label: "加入", onTap: () { _taskController.markTaskCompleted(task.id!); Get.back(); }, clr: primaryClr, context: context), _bottomSheetButton( label: "删除", onTap: () { _taskController.delete(task); Get.back(); }, clr: Colors.red[400]!, context: context), const SizedBox( height: 20, ), _bottomSheetButton( label: "关闭", onTap: () { Get.back(); }, clr: Colors.red[400]!, isClose: true, context: context), const SizedBox(height: 10), ]), ), ); } _bottomSheetButton({ required String label, required Function()? onTap, required Color clr, bool isClose = false, required BuildContext context, }) { return GestureDetector( onTap: onTap, child: Container( margin: const EdgeInsets.symmetric(vertical: 4), height: 55, width: MediaQuery.of(context).size.width * 0.9, decoration: BoxDecoration( border: Border.all( width: 2, color: isClose == true ? Get.isDarkMode ? Colors.grey[600]! : Colors.grey[400]! : clr), borderRadius: BorderRadius.circular(20), color: isClose == true ? Colors.transparent : clr, ), child: Center( child: Text( label, style: isClose ? titleStyle : titleStyle.copyWith(color: Colors.white), )), ), ); } _addDateBar() { return Container( margin: const EdgeInsets.only( top: 20, left: 20, ), child: DatePicker( DateTime.now(), height: 100, width: 80, initialSelectedDate: DateTime.now(), selectionColor: primaryClr, selectedTextColor: Colors.white, dateTextStyle: GoogleFonts.lato( textStyle: const TextStyle( fontSize: 20, fontWeight: FontWeight.w600, color: Colors.grey), ), dayTextStyle: GoogleFonts.lato( textStyle: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.grey), ), monthTextStyle: GoogleFonts.lato( textStyle: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: Colors.grey), ), onDateChange: (date) { setState(() { _selectedDate = date; }); }, ), ); } _addTaskBar() { return Container( margin: const EdgeInsets.only(right: 20, top: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( margin: const EdgeInsets.symmetric
相关产品推荐
相关产品推荐

