Flutter Web中如何实现TextFormField的响应式布局?
实现Row中TextFormField的响应式垂直堆叠效果
核心思路是根据可用宽度动态切换布局:当容器宽度小于设定阈值时,用Column垂直排列;宽度足够时用Row横向排列。下面是两种可靠的实现方案:
方案一:用LayoutBuilder(推荐)
LayoutBuilder能获取父组件的实际可用约束,比直接取屏幕宽度更精准,适合嵌套布局场景:
class ResponsiveFormFields extends StatelessWidget { @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { // 自定义宽度阈值,按需调整 final bool shouldStack = constraints.maxWidth < 600; return Flex( direction: shouldStack ? Axis.vertical : Axis.horizontal, gap: 16, // 控件间距,Row/Column通用 children: [ Expanded( child: TextFormField( decoration: const InputDecoration(labelText: '用户名'), ), ), Expanded( child: TextFormField( decoration: const InputDecoration(labelText: '邮箱'), ), ), Expanded( child: TextFormField( decoration: const InputDecoration(labelText: '手机号'), ), ), ], ); }, ); } }
关键细节:
- 用
Flex替代单独写Row/Column,通过direction参数动态切换布局方向,减少重复代码。 Expanded确保在Row模式下控件平分宽度,Column模式下控件占满父容器宽度,避免布局溢出或留白。- 阈值(600dp)可根据设计规范调整,比如平板端设为768dp。
方案二:用MediaQuery(全屏场景适用)
如果组件是全屏布局,直接通过屏幕宽度判断更简单:
class ResponsiveFormFields extends StatelessWidget { @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; final bool shouldStack = screenWidth < 600; return shouldStack ? Column( gap: 16, children: [ TextFormField(decoration: const InputDecoration(labelText: '用户名')), TextFormField(decoration: const InputDecoration(labelText: '邮箱')), TextFormField(decoration: const InputDecoration(labelText: '手机号')), ], ) : Row( gap: 16, children: [ Expanded(child: TextFormField(decoration: const InputDecoration(labelText: '用户名'))), Expanded(child: TextFormField(decoration: const InputDecoration(labelText: '邮箱'))), Expanded(child: TextFormField(decoration: const InputDecoration(labelText: '手机号'))), ], ); } }
注意事项:
- 若组件嵌套在有固定宽度的父容器中,MediaQuery会取屏幕宽度而非父容器宽度,此时优先用LayoutBuilder方案。
- 可根据需求添加动画过渡,比如用
AnimatedSwitcher实现布局切换时的平滑效果。
内容的提问来源于stack exchange,提问作者Eder Savillon
相关产品推荐
相关产品推荐

