Flutter开发中无法缩小ElevatedButton停止按钮尺寸的问题求助
问题描述
正在复刻苹果备忘录的录音按钮效果,需要缩小停止状态下的按钮尺寸。先后尝试了不使用SizedBox包裹、使用SizedBox包裹ElevatedButton两种实现方式,最终呈现的效果完全一致,即便将ElevatedButton嵌入SizedBox组件中也无法实现预期的小尺寸效果。
原始代码
Container _RecordButton(){ return Container( height: 90, width: 90, decoration: BoxDecoration( border: Border.all( width: 4.0, color: Colors.grey, ), shape: BoxShape.circle, ), child: Padding( padding: EdgeInsets.all(4.0), child: isRecording == false? _createRecordElevatedButton() : _createStopElevatedButton()),); } ElevatedButton _createRecordElevatedButton( {IconData icon, Function onPressFunc}) { return ElevatedButton( onPressed: () { if (isRecording = false){ setState(() { isRecording = true; }); }}, style: ButtonStyle( shape: MaterialStateProperty.all(CircleBorder()), padding: MaterialStateProperty.all(EdgeInsets.all(20)), backgroundColor: MaterialStateProperty.all(Colors.red), // <-- Button color /*overlayColor: MaterialStateProperty.resolveWith<Color>((states) { if (states.contains(MaterialState.pressed)) return Colors.red; // <-- Splash color }*/)); } SizedBox _createStopElevatedButton( {IconData icon, Function onPressFunc}) { return SizedBox( height: 14, width: 14, child: ElevatedButton( onPressed: () { /* if (isRecording = true){ setState(() { isRecording = false; }); }*/ }, style: ButtonStyle( fixedSize: MaterialStateProperty.all(Size(10,10)), shape: MaterialStateProperty.all<RoundedRectangleBorder>( RoundedRectangleBorder( borderRadius: BorderRadius.circular(16.0), side: BorderSide(color: Colors.red) ) ), padding: MaterialStateProperty.all(EdgeInsets.all(20)), backgroundColor: MaterialStateProperty.all(Colors.red), // <-- Button color /*overlayColor: MaterialStateProperty.resolveWith<Color>((states) { if (states.contains(MaterialState.pressed)) return Colors.red; // <-- Splash color }*/)), ); }
问题原因
- 最核心的冲突是停止按钮的内边距设置:你给停止按钮配置了
EdgeInsets.all(20)的全向内边距,内边距属于按钮自身布局尺寸的一部分,20的边距意味着按钮内容区域四周至少要留出20的空白,算下来按钮本身尺寸至少是40以上,直接覆盖了你给SizedBox和fixedSize配置的小尺寸参数,最终渲染出来的按钮自然会被撑大。 - Material组件的ElevatedButton默认自带最小尺寸约束,默认最小点击区域是48*48,如果不显式覆盖
minimumSize参数,哪怕你把其他尺寸参数设的再小,也会被默认最小尺寸限制撑大。 - 代码里存在基础语法错误:状态判断处
if (isRecording = false)是赋值操作,不是布尔值相等判断==,会导致录音状态切换逻辑本身就无法正常运行。 - 圆角参数和尺寸不匹配:你给尺寸仅14的停止按钮设置了16的圆角,视觉上会出现形状溢出的问题。
修复方案
- 调整停止按钮的内边距为
EdgeInsets.zero,移除多余的内边距撑大问题 - 给停止按钮的ButtonStyle追加
minimumSize: MaterialStateProperty.all(Size.zero),覆盖默认的最小尺寸限制,如果需要保留足够的点击热区,可以通过tapTargetSize: MaterialTapTargetSize.shrinkWrap来调整,不要靠内边距撑大按钮视觉尺寸 - 修正状态判断的语法错误,把赋值符号
=改为相等判断==,补全停止状态下的状态切换逻辑 - 调整停止按钮的圆角参数到和尺寸匹配的数值,14大小的方形停止按钮设置3-4的圆角即可匹配苹果备忘录的视觉效果
修复后的停止按钮核心代码参考:
SizedBox _createStopElevatedButton() { return SizedBox( height: 30, // 可根据实际视觉需求调整尺寸 width: 30, child: ElevatedButton( onPressed: () { if (isRecording == true){ setState(() { isRecording = false; }); } }, style: ButtonStyle( // 覆盖默认最小尺寸 minimumSize: MaterialStateProperty.all(Size.zero), // 移除多余内边距 padding: MaterialStateProperty.all(EdgeInsets.zero), // 缩小点击热区避免多余占位 tapTargetSize: MaterialTapTargetSize.shrinkWrap, shape: MaterialStateProperty.all<RoundedRectangleBorder>( RoundedRectangleBorder( borderRadius: BorderRadius.circular(4.0), ) ), backgroundColor: MaterialStateProperty.all(Colors.red), ), ), ); }
内容的提问来源于stack exchange,提问作者Laurent Thomas
相关产品推荐
相关产品推荐

