改变 button style 主要有两种方法,styleFrom,ButtonStyle。
styleFrom
styleFrom 是静态方法,内部调用 ButtonStyle,从这个逻辑上就可以看出来,styleFrom 用起来简单,但灵活性不如 ButtonStyle。设置的值对所有 MaterialState 都生效。
ElevatedButton( style: ElevatedButton.styleFrom( foregroundColor: Colors.green ), child: Text( 'IAM17 flutter 天天更新', ), onPressed: () { print('a'); } ); 复制代码
想精细的控制颜色,直接用 ButtonStyle
ButtonStyle
把刚才的 foregroundColor 换成 buttonStyle 这样写
ElevatedButton( style: ButtonStyle(foregroundColor: MaterialStateProperty.all<Color>(Colors.green)), child: Text( 'IAM17', ), onPressed: () { print('pressed'); } ); 复制代码
看起来代码更多了,用 buttonStyle 更多的是用 resolveWith,更精细的控制样式。当 return null 的时候,就用默认的样式。
ElevatedButton( style: ButtonStyle( overlayColor: MaterialStateProperty.resolveWith<Color?>((states) { if (states.contains(MaterialState.hovered)) { return Colors.green; } return null; })), child: Text( 'flutter', ), onPressed: () { print('pressed'); }); 复制代码
如果有很多地方用,每次都写 resolveWith 方法还是很麻烦的,我们可以定义一个类。
class _TextButtonDefaultOverlay extends MaterialStateProperty<Color?> { _TextButtonDefaultOverlay(this.primary); final Color primary; @override Color? resolve(Set<MaterialState> states) { if (states.contains(MaterialState.hovered)) return primary.withOpacity(0.04); if (states.contains(MaterialState.focused) || states.contains(MaterialState.pressed)) return primary.withOpacity(0.12); return null; } @override String toString() { return '{hovered: ${primary.withOpacity(0.04)}, focused,pressed: ${primary.withOpacity(0.12)}, otherwise: null}'; } } 复制代码
override resolve 方法就可以了。
ElevatedButton( style: ButtonStyle( overlayColor:_TextButtonDefaultOverlay(Colors.green), child: Text( '天天更新', ), onPressed: () { print('pressed'); }); 复制代码
上面说的两种方法都是改变某个 button,要想改变整个树中的 button,用 TextButtonTheme
, ElevatedButtonTheme
, 和 OutlinedButtonTheme
比如
ElevatedButtonTheme( data: ElevatedButtonThemeData( style: ButtonStyle( textStyle: MaterialStateProperty.all<TextStyle>( TextStyle(fontSize: 20)))), child: ElevatedButton( ... 复制代码
需要注意几点。
- foregroundColor 用来定义文本颜色,就不要用 textStyle 中的 color了。
- 优先设置属性值,属性没有的再设置 style,style 没有的,再设置 child 的属性值。
- fixedSize 可以设置按钮的大小,但是会受到 minimumSize 和 maximumSize 的限制。
- 按钮默认是有 padding的。
- tapTargetSize 可以增加点击区域。
MaterialState 枚举
直接到这里看吧。有图有讲解。我不就搬过来了。ButtonStyle 和 MaterialStateProperty
其它的属性什么的就都很简单了,试试就都知道了,就不再赘述了。