Flutter 自定义渐变按钮 GradientButton
  xx2YH4ad7R0N 2023年11月02日 38 0


在Flutter中页面UI通常都是由一些低级别组件组合而成,当我们需要封装一些通用组件时,应该首先考虑是否可以通过组合其它组件来实现,如果可以,则应优先使用组合,因为直接通过现有组件拼装会非常简单、灵活、高效。

Flutter 自定义渐变按钮 GradientButton_渐变色

1. 实例:自定义渐变按钮

1. 实现GradientButton

Flutter Material组件库中的按钮默认不支持渐变背景,为了实现渐变背景按钮,我们自定义一个GradientButton组件,它需要支持一下功能:

  • 背景支持渐变色
  • 手指按下时有涟漪效果
  • 可以支持圆角

DecoratedBox可以支持背景色渐变和圆角,InkWell在手指按下有涟漪效果,所以我们可以通过组合DecoratedBox和InkWell来实现GradientButton

class GradientButton extends StatelessWidget {
const GradientButton({
Key? key,
this.colors,
this.width,
this.height,
this.borderRadius,
required this.tapCallback,
required this.child,
this.disable = false,
}) : super(key: key);

final List<Color>? colors; // 渐变色数组
final double? width; // 按钮 宽
final double? height; // 按钮 高
final BorderRadius? borderRadius; // 按钮 圆角

final GestureTapCallback tapCallback;
final bool disable; // 禁用

final Widget child; // 子组件

@override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);

List<Color> _colors = [];
if (disable) {
//确保colors数组不空
_colors = [Colors.grey.withAlpha(100), Colors.grey.withAlpha(100)];
} else {
//确保colors数组不空
_colors = colors ?? [theme.primaryColor, theme.primaryColorDark];
}

return DecoratedBox(
decoration: BoxDecoration(
borderRadius: borderRadius,
gradient: LinearGradient(colors: _colors),
),
child: Material(
type: MaterialType.transparency, // 透明材质 用于绘制墨水飞溅和高光
child: InkWell(
onTap: disable ? null : tapCallback,
splashColor: _colors.last,
borderRadius: borderRadius,
enableFeedback: !disable, // 是否给予操作反馈
highlightColor: Colors.transparent,
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(width: width, height: height),
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DefaultTextStyle(
style: TextStyle(fontWeight: FontWeight.bold),
child: child,
),
),
),
),
),
),
);
}
}

可以看到GradientButton是由DecoratedBox、Padding、Center、InkWell等组件组合而成。更多功能可以根据实际需要来完善。

2. 使用GradientButton

class MSGradientButtonDemo extends StatelessWidget {
const MSGradientButtonDemo({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("GradientButton")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GradientButton(
tapCallback: () => print("Button Clicked 1"),
child: Text("Submit 1"),
colors: [Colors.orange, Colors.cyan],
height: 50,
),
GradientButton(
tapCallback: () => print("Button Clicked 2"),
child: Text("Submit 2"),
colors: [Colors.cyan, Colors.green],
height: 50,
),
GradientButton(
tapCallback: () => print("Button Clicked 3"),
child: Text("Submit 3"),
colors: [Colors.yellow, Colors.red, Colors.orange],
height: 50,
),
GradientButton(
tapCallback: () => print("Button Clicked 4"),
child: Text("Submit 4"),
colors: [Colors.orange, Colors.cyan],
height: 50,
width: 200,
borderRadius: BorderRadius.circular(8),
),
GradientButton(
tapCallback: () => print("Button Clicked 5"),
child: Text("enable 5"),
width: 200,
height: 50,
borderRadius: BorderRadius.circular(8),
colors: [Colors.grey, Colors.red],
disable: false,
),
GradientButton(
tapCallback: () => print("Button Clicked 6"),
child: Text("Disable 6"),
width: 200,
height: 50,
borderRadius: BorderRadius.circular(8),
disable: true,
)
],
),
),
);
}
}

Flutter 自定义渐变按钮 GradientButton_数组_02

2. 总结

通过组合的方式定义组件和我们之前写界面并无差异,不过在抽离出单独的组件时我们要考虑代码规范性,如必要参数要用required关键词标注,对于可选参数在特定场景需要判空或设置默认值等。这是由于使用者大多时候可能不了解组件的内部细节,所以为了保证代码健壮性,我们需要在用户错误地使用组件时能够兼容或报错提示(使用assert断言函数)。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  b1UHV4WKBb2S   2023年11月13日   27   0   0 渐变色f5
  b1UHV4WKBb2S   2023年11月13日   28   0   0 阴影模糊数组
  b1UHV4WKBb2S   2023年11月13日   33   0   0 裁剪ideflutter
  b1UHV4WKBb2S   2023年11月13日   26   0   0 flutterDart
xx2YH4ad7R0N