Flutter TabBar含3个标签时,第三标签内容超出屏幕宽度问题
Flutter TabBar布局异常问题
问题现象
- TabBar包含3个标签:Overview、QC History、Inventory Stock
- 首次进入第三个Inventory标签时,页面内容宽度异常拉伸,部分元素超出屏幕范围,调试控制台无报错信息
- 切换到其他页面后再返回第三个标签,内容尺寸恢复正常
- 仅当TabBar为3个标签时出现此问题,2、4、5个标签均无异常
状态说明
- 异常状态:页面组件宽度超出屏幕边界,布局整体拉伸变形
- 正常状态:内容完全适配屏幕宽度,布局显示正常
相关代码
Dashboard代码
class DashboardScreen extends StatelessWidget { static const String routeName = '/dashboard'; const DashboardScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return DefaultTabController( length: 3, child: Scaffold( appBar: AppBar( title: const Text('Dashboard'), centerTitle: true, bottom: const TabBar( tabs: [ Tab( text: 'Overview', icon: Icon(Icons.analytics), ), Tab( text: 'QC History', icon: Icon(Icons.verified_user), ), Tab( text: 'Inventory Stock', icon: Icon(Icons.inventory), ), ], ), ), body: TabBarView( children: [ const AnalyticsScreen(), const QualityControlScreen(), InventoryScreen(), ], ), ), ); } }
InventoryScreen(第三个标签页面)代码
class InventoryScreen extends StatelessWidget { static const String routeName = '/inventory'; InventoryScreen({Key? key}) : super(key: key); // Dummy data representing items in the factory's inventory final List<InventoryItem> inventoryItems = [ InventoryItem( name: 'Item A', quantity: 10, description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', ), InventoryItem( name: 'Item B', quantity: 5, description: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco.', ), InventoryItem( name: 'Item C', quantity: 15, description: 'Duis aute irure dolor in reprehenderit in voluptate velit.', ), ]; @override Widget build(BuildContext context) { return ListView.builder( itemCount: inventoryItems.length, itemBuilder: (context, index) { final item = inventoryItems[index]; return CustomCardWidget( child: Column( children: [ ListTile( title: Text(item.name), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Quantity: ${item.quantity}'), const SizedBox(height: 4), Text(item.description), ], ), onTap: () { // TODO: Handle tapping on an inventory item }, ), const SizedBox(height: 8), LinearProgressIndicator( value: item.quantity / 100, ), const SizedBox(height: 8), SizedBox( height: 200, child: SfCartesianChart( primaryXAxis: CategoryAxis(), series: <ChartSeries>[ ColumnSeries<InventoryItem, String>( dataSource: [item], xValueMapper: (InventoryItem item, _) => item.name, yValueMapper: (InventoryItem item, _) => item.quantity, color: Colors.blue, ), ], ), ), ], ), ); }, ); } }
QualityControlScreen代码
class QualityControlScreen extends StatelessWidget { static const String routeName = '/quality-control'; const QualityControlScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const SingleChildScrollView( child: Padding( padding: EdgeInsets.all(16.0), child: Column( children: [ QualityControlItem( testId: 'QC001', testName: 'Test A', status: QualityControlStatus.passed, ), QualityControlItem( testId: 'QC002', testName: 'Test B', status: QualityControlStatus.failed, ), QualityControlItem( testId: 'QC003', testName: 'Test C', status: QualityControlStatus.pending, ), ], ), ), ); } }
AnalyticsScreen代码
class AnalyticsScreen extends StatelessWidget { const AnalyticsScreen({super.key}); @override Widget build(BuildContext context) { return const SingleChildScrollView( child: Padding( padding: EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ProductionProgress(), Attendance(), InventoryStock(), QualityControlHistory(), ], ), ), ); } }
已尝试的解决方法
- 将第三个标签中的
ListView.builder替换为SingleChildScrollView,问题未解决 - 替换第三个标签内容为简单文本组件,问题仍复现
恳请帮忙排查并解决该布局问题。
内容的提问来源于stack exchange,提问作者OZTech Lab
相关产品推荐
相关产品推荐

