Flutter实现一个支持渐变背景的Button示例详解
目录
- Flutter中的按钮
- 不完美的地方
- 在child中处理
- 外面套一个wrapper
- MaterialStateProperty
- MaterialStatesController
- 边距问题
- EnhancedButton
Flutter中的按钮
自Flutter 1.20 新增了ButtonStyleButton 系列按钮,可以说非常好用了,默认样式比之前漂亮了许多,扩展性也增加了很多。按钮样式统一由ButtonStyle这个类提供,支持根据各种状态(MaterialState)变化的属性,也增强了桌面平台也友好性。
值 | 状态 |
---|---|
hovered | 鼠标滑入 |
focused | 焦点 |
pressed | 按下 |
dragged | 拖动 |
selected | 选中 |
scrolledUnder | 与滚动内容叠加 |
disabled | 不可用 |
error | 错误 |
最常用到的就是pressed和disabled还有桌面端的hovered。
可变化的属性
属性 | 说明 | 备注 |
---|---|---|
backgroundColor | 背景色 | Flutter3.3版本之前对应 primary或onPrimary |
foregroundColor | 前景色(文本颜色) | Flutter3.3版本之前对应 primary或onPrimary |
elevation | 模拟物理深度 | 其实就是阴影浅重 |
fixedSize | 按钮尺寸 | 受最大尺寸和最小尺寸和布局影响 |
maxinumSize | 最大尺寸 | |
minimumSize | 最小尺寸 | |
mouseCursor | 鼠标图标 | |
overlayColor | 高亮色 | |
padding | 内容边距 | |
shadowColor | 阴影颜色 | |
shape | 按钮形状 | 由OutlinedBorder定义 |
side | 边框样式 | |
surfaceTintColor | Material3使用的材质颜色 | |
textStyle | 文本样式 |
可以看到默认按钮样式,主要针对的是形状,颜色和交互效果(overlay splash),普通情况下也够用的。
不完美的地方
但是,要想进一步定制按钮效果,比如设计师提供的按钮,是渐变色的,那怎么办呢? 比较常见的做法是用Container自己写一个按钮出来。Container的decoration可以说非常好用了,支持单色,渐变,以及装饰图。AnimatedContainer还能对各种属性做动画展现。
但是 按钮要做的事情,不止是一个背景这么简单。比如上面提到的状态,以及点击反馈,语义化等等。要使用Container把这一整套实现出来,会非常繁琐。
在child中处理
Button的child可以是任何Widget,那么,把Container放到child里来实现定制背景怎样呢?且不说Button默认的padding之类的,Button的效果,都是在背景层实现的,child中的任何可见元素,都会覆盖在这层背景之上。简单来说,就是覆盖背景的同时会覆盖掉Button的Splash等overlay效果。
外面套一个wrapper
把Button套进Container里,在Container的decoration中做背景。这个方法首先要做的就是把Button的背景和阴影去除,那么除了在Container里做背景,还要模拟出Button的阴影。
AnimatedContainer( duration: Duration(milliseconds:200), width: width, height: height, transformAlignment: Alignment.center, clipBehavior: clipBehavior, decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.blue,Colors.red] ), shadow: [BoxShadow( ... )] ), child: ElevatedButton( //... ), );
初步来看,这个方法还是可行的。重点就在于怎么把需要增强的属性组织起来,并且和按钮的状态结合起来了。
MaterialStateProperty
按钮的动态属性,都是基于这个状态属性处理的,它可以根据当前的属性集合,匹配到合适的属性提供回来。
MaterialStatesController
按钮状态的控制器,可以通过这个控制器来监听按钮的状态,做出对应处理
边距问题
ButtonStyle中有一个tapTargetSize属性(非动态属性),定义了点击目标的扩展边距,在移动设备上默认情况下按钮会向上/下多出一点边距,导致Container的背景比按钮尺寸多出一块,按钮的overlay效果铺不满,手动指定TapTargetSize.shrinkWrap就可以了。
EnhancedButton
结合以上想法,整理了style及wrapper实现了一个增加的按钮,效果如下
本来命名的ExtendedButton,结果被一个不维护的包占用了名字,就改成了EnhancedButton。虽然目前还有些许不完美的方面,以后再慢慢优化吧。
github: github.com/shirne/exte…
pub: pub.flutter-io.cn/packages/en…
以上就是Flutter实现一个支持渐变背景的Button示例详解的详细内容,更多关于Flutte 渐变背景 Button的资料请关注我们其它相关文章!