Flutter Button封装实践 2023-07-26 周三
2023-08-05 本文已影响0人
勇往直前888
简介
项目中用到的按钮,主要分为以下几类,现在准备封装一下:
![](https://img.haomeiwen.com/i1186939/f79f953e632d9d3e.png)
实现方式
-
方案1: 用Flutter提供的各种Button
-
方案2:用Container模拟
在这里,我们选择方案2:用Container模拟
属性设置
- 按照类型,按钮分为主和次两种
/// 按钮类型
enum PandaButtonType {
main,
second,
}
- 按照大小分,分为大80,中64,小56三种;单位都是像素,代码中要除以2
/// 按钮类型
enum PandaButtonSize {
big,
middle,
small,
}
-
不可用的时候,都是一种样式,这个用一个参数表示就可以了
final bool enable;
并且给默认值true
,不可用是属于不常见的特殊状态
this.enable = true,
-
颜色分为明亮和暗黑两种,这个我们用了一个统一工具封装了一下,取一个名字,分别定义命令和暗黑两种模式下的颜色值。其实就是两个字典,比如
PandaColorConfig().text333333
就是下面的定义
Map<String, Color?> get lightInfo => {
PandaColorSring.text333333: const Color(0xFF333333),
/// 其他的颜色定义
};
Map<String, Color?> get darkInfo => {
PandaColorSring.text333333: const Color(0xFFC2C2CA),
/// 其他的颜色定义
};
也就是命令模式是#333333
,暗黑模式是#C2C2CA
-
文字居中,
padding
写死就可以了,基本上不起作用; -
width
一般需要外面给,不给的话,就会靠文本和padding
撑开; -
margin
当做参数放出来有些场景可以带来方便; -
点击响应用一个回调函数就可以了。这种套娃式的编程,回调函数是不可避免的。
样例代码
不能直接copy,仅供参考
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:pandabuy/theme/panda_color_config.dart';
class PandaButton extends StatelessWidget {
const PandaButton({
Key? key,
required this.text,
this.enable = true,
this.type = PandaButtonType.main,
this.size = PandaButtonSize.big,
this.margin,
this.width,
this.onClick,
}) : super(key: key);
final String text;
final bool enable;
final PandaButtonType type;
final PandaButtonSize size;
final EdgeInsetsGeometry? margin;
final double? width;
final void Function()? onClick;
@override
Widget build(BuildContext context) {
/// 背景色
Color backgroundColor;
if (enable) {
if (type == PandaButtonType.main) {
backgroundColor = PandaColorConfig().background11BA66Both;
} else {
backgroundColor = PandaColorConfig().backgroundFFFFFF;
}
} else {
backgroundColor = PandaColorConfig().backgroundD8D8D8;
}
/// 高度
double height = 40.h;
if (size == PandaButtonSize.middle) {
height = 32.h;
}
if (size == PandaButtonSize.small) {
height = 28.h;
}
/// 边框
BoxBorder? border;
if (enable) {
if (type == PandaButtonType.second) {
border = Border.all(
color: PandaColorConfig().borderCCCCCC,
width: 0.5,
);
}
}
/// 文本颜色
Color textColor;
if (enable) {
if (type == PandaButtonType.main) {
textColor = PandaColorConfig().textFFFFFFBoth;
} else {
textColor = PandaColorConfig().text333333;
}
} else {
textColor = PandaColorConfig().text999999;
}
/// 文本大小
double fontSize = 16.sp;
if (size == PandaButtonSize.middle) {
fontSize = 14.sp;
}
if (size == PandaButtonSize.small) {
fontSize = 12.sp;
}
/// 文本字重
FontWeight fontWeight = FontWeight.w600;
if ((size == PandaButtonSize.big) && (type == PandaButtonType.second)) {
fontWeight = FontWeight.w500;
}
if ((size == PandaButtonSize.middle) || (size == PandaButtonSize.small)) {
fontWeight = FontWeight.w400;
}
return GestureDetector(
onTap: () {
if (enable) {
if (onClick != null) {
onClick!();
}
}
},
child: Container(
width: width,
height: height,
margin: margin,
padding: EdgeInsets.symmetric(horizontal: 8.w),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(5.r),
border: border,
),
child: Center(
child: Text(
text,
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontWeight: fontWeight,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
),
);
}
}
/// 按钮类型
enum PandaButtonType {
main,
second,
}
/// 按钮类型
enum PandaButtonSize {
big,
middle,
small,
}