如何避免Modal Bottom Sheet中Column组件底部溢出?
解决Modal Bottom Sheet中Column底部溢出问题
问题根源
小屏设备(如iPhone SE)上,showModalBottomSheet默认最大高度限制(通常为屏幕高度的50%)不足以容纳所有子组件,再加上系统底部安全区域的遮挡,导致Column出现溢出或最后一个组件被截断。
解决方案
通过调整底部弹窗的高度约束、适配安全区域,同时优化布局间距来解决问题:
- 设置弹窗最大高度约束:扩大弹窗允许的最大高度,确保能容纳所有子组件
- 使用SafeArea适配系统安全区域:避免内容被设备底部指示器遮挡
- 优化布局间距:添加合理的内边距和组件间距,提升视觉体验
修改后的完整代码
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: const Center( child: AttributionButton(), )); } } class AttributionCard extends StatelessWidget { final String cardName; const AttributionCard({super.key, required this.cardName}); @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, height: 80, child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), side: const BorderSide(color: Colors.black, width: 1.0)), child: InkWell( borderRadius: BorderRadius.circular(10.0), child: Container( alignment: Alignment.center, child: Text(cardName, style: const TextStyle(fontSize: 20)), )), ), ); } } class AttributionButton extends StatelessWidget { const AttributionButton({super.key}); @override Widget build(BuildContext context) { return FloatingActionButton( backgroundColor: Colors.transparent, mini: true, elevation: 0, highlightElevation: 0, heroTag: 'f10', onPressed: () { showModalBottomSheet( context: context, // 调整弹窗最大高度为屏幕的80%,适配小屏设备 constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height * 0.8, ), builder: (BuildContext context) { // 用SafeArea避免内容被系统底部指示器遮挡 return SafeArea( child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('Attributions', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black)), TextButton( style: TextButton.styleFrom( backgroundColor: Colors.grey.withOpacity(0.23), shape: const CircleBorder()), onPressed: () { Navigator.of(context).pop(); }, child: const Icon( Icons.clear_sharp, color: Colors.black, )), ]), const SizedBox(height: 8), const AttributionCard( cardName: 'FlutterMap', ), const SizedBox(height: 8), const AttributionCard( cardName: '© OpenStreetMap', ), const SizedBox(height: 8), const AttributionCard( cardName: '© MapTiler', ), const SizedBox(height: 8), const AttributionCard( cardName: '© StadiaMaps', ), ], ), ), ); }, ); }, child: const Icon( Icons.info_outline_rounded, color: Colors.black, ), ); } }
内容的提问来源于stack exchange,提问作者coscinodibruco
相关产品推荐
相关产品推荐

