为何ElevatedButton设0 elevation时,styleFrom有阴影而ButtonStyle无?


问题
为何将ElevatedButton的elevation设为0时,使用.styleFrom()会显示阴影,而使用ButtonStyle()却不会?按理解,.styleFrom()函数会把各类参数转换为MaterialStateProperty/ButtonStyleButton,之后自行调用ButtonStyle()函数。既然二者逻辑几乎一致,为何阴影表现不同?另外,该如何修改这个小阴影的颜色?或者有没有其他方法让0 elevation的按钮在按下时显示小阴影?
两种实现代码
使用ButtonStyle的实现
ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(const Color.fromARGB(255, 215, 213, 245)), elevation:MaterialStateProperty.all<double>(0), padding: MaterialStateProperty.all<EdgeInsetsGeometry>(const EdgeInsets.all(0)), shape: MaterialStateProperty.all<OutlinedBorder>(RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)) ), ), onPressed: () {}, child: const Text('Starting stack: 5000',style: TextStyle(fontSize: 20.0, color: Colors.black)), )
使用styleFrom的实现
... style: ElevatedButton.styleFrom( elevation:0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.0) ), padding: const EdgeInsets.all(0), onPrimary: Colors.white, primary: const Color.fromARGB(255, 215, 213, 245), textStyle: const TextStyle(fontSize: 20.0), ), ...
原因与解决方案
差异原因
styleFrom并非简单转参数后调用ButtonStyle,它内部会为不同状态设置默认elevation值:你传入的elevation:0仅作用于按钮默认(未按下)状态,而按下状态的elevation会被默认设为2,这就是阴影出现的原因。
直接用ButtonStyle时,MaterialStateProperty.all(0)会把所有状态的elevation固定为0,所以按下时无阴影。
修改阴影颜色
要修改按下时的阴影色,需通过shadowColor结合状态处理:
- 用
styleFrom的方式:ElevatedButton.styleFrom( elevation: 0, // 全局阴影色 shadowColor: Colors.blue, // 或针对按下状态单独设置 shadowColor: MaterialStateProperty.resolveWith((states) { return states.contains(MaterialState.pressed) ? Colors.red : null; }), // 其他参数... ) - 用
ButtonStyle的方式:ButtonStyle( elevation: MaterialStateProperty.resolveWith((states) { return states.contains(MaterialState.pressed) ? 2 : 0; }), shadowColor: MaterialStateProperty.resolveWith((states) { return states.contains(MaterialState.pressed) ? Colors.green : null; }), // 其他参数... )
让0 elevation按钮按下时显示阴影的方法
有两种常用方式:
- 用styleFrom:它默认会给按下状态设elevation=2,若要自定义值,可通过
MaterialStateProperty覆盖:ElevatedButton.styleFrom( elevation: MaterialStateProperty.resolveWith((states) { return states.contains(MaterialState.pressed) ? 3 : 0; }), // 其他参数... ) - 用ButtonStyle:手动为不同状态设置elevation:
ButtonStyle( elevation: MaterialStateProperty.resolveWith((states) { return states.contains(MaterialState.pressed) ? 2 : 0; }), // 其他参数... )
内容的提问来源于stack exchange,提问作者Thegoliksim
相关产品推荐
相关产品推荐

