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完成了一个添加的按钮,作用如下

【Flutter】完成一个支撑突变布景的Button

原本命名的ExtendedButton,成果被一个不维护的包占用了姓名,就改成了EnhancedButton。虽然目前还有少许不完美的方面,以后再渐渐优化吧。

github: github.com/shirne/exte…

pub: pub.flutter-io.cn/packages/en…