> 技术文档 > 开源 我写了个 Flutter 组件 ducafe_ui_core

开源 我写了个 Flutter 组件 ducafe_ui_core


开源 我写了个 Flutter 组件 ducafe_ui_core

开源 我写了个 Flutter 组件 ducafe_ui_core

视频

https://www.bilibili.com/video/BV17PPWeAEom/

前言

原文 Flutter 组件 ducafe_ui_core:提升开发效率的利器

许多群友询问我关于 ducafe_ui_core 的使用方法。这个组件是我将之前项目中频繁重复使用的功能独立抽取出来,以便在新项目中引入,从而提升开发效率。如果你想系统地学习 Flutter,欢迎关注我的新课程 woo2025。在本文中,我将介绍 ducafe_ui_core 包含的各种功能。

参考

https://ducafecat.com/course/flutter-woo-2025

https://pub.dev/packages/ducafe_ui_core

功能介绍

添加依赖

https://pub.dev/packages/ducafe_ui_core

pubspec.yaml

dependencies: ... ducafe_ui_core: ^1.0.6

1 设计稿适配

编辑 lib/main.dart ,初始屏幕适配

class MyApp extends StatelessWidget { const MyApp({super.key});  Widget build(BuildContext context) { return ScreenUtilInit( designSize: const Size(375, 812), builder: (context, child) { return MaterialApp( title: \'Flutter Demo\', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: \'Flutter Demo Home Page\'), ); }, ); }}

包裹 ScreenUtilInit

编写 lib/page1.dart

 Widget _buildView() { return Container( color: Colors.blue, width: 300.w, height: 300.h, child: Column( children: [ Text(\'Page One\'), ], ), ); }

通过 .w .h 动态适配计算

编辑 lib/main.dart ,跳转到新页面

 void _incrementCounter() { // 上下文导航操作 context.navigator.pushMaterial(const PageOne()); // 原始写法 // Navigator.push( // context, MaterialPageRoute(builder: (context) => const PageOne())); }

用 web 方式启动,方便测试内容区域尺寸变化

方正屏幕

开源 我写了个 Flutter 组件 ducafe_ui_core

又长又矮屏幕

开源 我写了个 Flutter 组件 ducafe_ui_core

2 视图层打薄

开源 我写了个 Flutter 组件 ducafe_ui_core

打薄后代码

 Widget _buildView() { return Text(\"ducafecat\") .fontSize(22) .alignment(Alignment.center) .borderRadius(all: 15) .ripple() .backgroundColor(Colors.white, animate: true) .clipRRect(all: 25) // clip ripple .borderRadius(all: 25, animate: true) .elevation( pressed ? 0 : 1, borderRadius: BorderRadius.circular(25), shadowColor: Color(0x30000000), ) // shadow borderRadius .padding(vertical: 12) // margin .onTap( () => print(\'onTap\'), ) .scale(all: pressed ? 0.95 : 1.0, animate: true) .animate(Duration(milliseconds: 150), Curves.easeOut) .tight( height: 80, width: 200, ) .center(); }

原始方式代码

Widget _buildView() { return Center( child: GestureDetector( onTapDown: (_) => setState(() => pressed = true), onTapUp: (_) => setState(() => pressed = false), onTapCancel: () => setState(() => pressed = false), child: AnimatedContainer( duration: Duration(milliseconds: 150), curve: Curves.easeOut, height: 80, width: 200, transform: Matrix4.identity()..scale(pressed ? 0.95 : 1.0), child: Material( color: Colors.white, elevation: pressed ? 0 : 1, shadowColor: Color(0x30000000), borderRadius: BorderRadius.circular(25), child: InkWell( onTap: () => print(\'onTap\'), borderRadius: BorderRadius.circular(25), child: Container(  padding: EdgeInsets.symmetric(vertical: 12),  alignment: Alignment.center,  child: Text( \"ducafecat\", style: TextStyle(  fontSize: 22, ),  ), ), ), ), ), ), );}

扩展方法:

  • animate: 为组件添加动画效果
  • align: 设置组件对齐方式
  • alignCenter: 居中对齐组件
  • alignLeft: 左对齐组件
  • alignRight: 右对齐组件
  • alignTop: 顶部对齐组件
  • alignBottom: 底部对齐组件
  • parent: 应用父组件
  • padding: 为组件添加内边距
  • paddingBottom: 添加底部内边距
  • paddingHorizontal: 添加水平内边距
  • paddingLeft: 添加左侧内边距
  • paddingRight: 添加右侧内边距
  • paddingTop: 添加顶部内边距
  • paddingVertical: 添加垂直内边距
  • paddingDirectional: 添加方向性内边距
  • sliverPadding: 为 Sliver 组件添加内边距
  • opacity: 设置组件透明度
  • offstage: 控制组件的可见性
  • neumorphism: 添加凹凸效果
  • boxShadow: 添加阴影效果
  • ripple: 添加涟漪效果
  • rotate: 旋转组件
  • scale: 缩放组件
  • translate: 平移组件
  • transform: 应用变换
  • overflow: 控制组件溢出行为
  • scrollable: 使组件可滚动
  • expanded: 在 Flex 容器中扩展组件
  • flexible: 在 Flex 容器中使组件灵活
  • positioned: 在 Stack 中定位组件
  • positionedDirectional: 在 Stack 中按方向定位组件
  • inkWell: 添加墨水效果和点击事件
  • safeArea: 将组件放置在安全区域
  • semanticsLabel: 添加语义标签
  • gestures: 添加手势识别
  • center: 居中组件
  • fittedBox: 使组件适应父组件
  • fractionallySizedBox: 根据父组件比例设置大小
  • card: 将组件包装在卡片中
  • limitedBox: 限制组件的最大大小
  • material: 将组件包装在 Material 中
  • mouseRegion: 添加鼠标交互区域

3 主题样式

快速写一个依据当前主题的主按钮。

开源 我写了个 Flutter 组件 ducafe_ui_core

通过 context.colors.scheme 方式读取样式配置。

 Widget _buildView() { var scheme = context.colors.scheme; return Text(\"ducafecat\") .fontSize(22) .fontWeight(FontWeight.bold) .textStyle(TextStyle(color: scheme.onPrimary)) .alignment(Alignment.center) .borderRadius(all: 15) .ripple() .backgroundColor(scheme.primary, animate: true) .clipRRect(all: 25) // clip ripple .borderRadius(all: 25, animate: true) .elevation( pressed ? 0 : 1, borderRadius: BorderRadius.circular(25), shadowColor: Color(0x30000000), ) // shadow borderRadius .padding(vertical: 12) // margin .onTap( () => print(\'onTap\'), ) .scale(all: pressed ? 0.95 : 1.0, animate: true) .animate(Duration(milliseconds: 150), Curves.easeOut) .tight( height: 80, width: 200, ) .center(); }

扩展:

  • primary: 主要颜色
  • primaryLight: 主要颜色的亮色版本
  • primaryDark: 主要颜色的暗色版本
  • canvas: 画布颜色
  • scaffoldBackground: 脚手架背景色
  • card: 卡片颜色
  • divider: 分割线颜色
  • focus: 焦点颜色
  • hover: 悬停颜色
  • highlight: 高亮颜色
  • splash: 水波纹颜色
  • unselectedWidget: 未选中部件的颜色
  • disabled: 禁用状态颜色
  • secondaryHeader: 次要标题颜色
  • dialogBackground: 对话框背景色
  • indicator: 指示器颜色
  • hint: 提示文字颜色
  • scheme: 完整的颜色方案
  • shadow: 阴影颜色

4 工具类

4.1 屏幕尺寸信息

示例:

context.screenWidth

扩展:

  • screenWidth: 获取屏幕宽度
  • screenHeight: 获取屏幕高度
  • bottomBarHeight: 获取底部导航栏高度
  • statusBarHeight: 获取状态栏高度
  • textScaleFactor: 获取文本缩放因子
  • scaleWidth: 获取宽度的缩放因子
  • scaleHeight: 获取高度的缩放因子
4.2 时间差

示例:

// 创建一个 5 秒的 DurationDuration fiveSeconds = 5.seconds;

扩展:

  • microseconds: 将数字转换为微秒的 Duration
  • milliseconds: 将数字转换为毫秒的 Duration
  • seconds: 将数字转换为秒的 Duration
  • minutes: 将数字转换为分钟的 Duration
  • hours: 将数字转换为小时的 Duration
  • days: 将数字转换为天的 Duration
  • months: 将数字转换为月的 Duration(假设一个月为 30 天)
  • quarters: 将数字转换为季度的 Duration(假设一个季度为 90 天)
  • quadrimesters: 将数字转换为四个月的 Duration(假设四个月为 120 天)
  • years: 将数字转换为年的 Duration(假设一年为 365 天)
  • future: 启动一个延迟 delayed
4.3 Icon 扩展
// 创建一个原始图标Icon originalIcon = Icon(Icons.star, size: 24, color: Colors.yellow);// 使用 copyWith() 创建一个新图标,修改大小和颜色Icon newIcon = originalIcon.copyWith(size: 32, color: Colors.red);// 仅修改图标大小Icon largerIcon = originalIcon.iconSize(48);// 仅修改图标颜色Icon blueIcon = originalIcon.iconColor(Colors.blue);
4.4 List 集合

示例:

List<Widget> widgets = [Widget1(), Widget2(), Widget3()];Widget column = widgets.toColumn( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, separator: Divider(),);

扩展:

  • toColumn(): 将 Widget 列表转换为 Column
  • toColumnSpace(): 将 Widget 列表转换为带有间距的 Column
  • toRow(): 将 Widget 列表转换为 Row
  • toRowSpace(): 将 Widget 列表转换为带有间距的 Row
  • toStack(): 将 Widget 列表转换为 Stack
  • toListView(): 将 Widget 列表转换为 ListView
  • toWrap(): 将 Widget 列表转换为 Wrap
4.5 媒体查询

示例:

class MyWidget extends StatelessWidget {  Widget build(BuildContext context) { // 获取屏幕宽度 double screenWidth = context.sizes.width; // 获取屏幕高度 double screenHeight = context.sizes.height; // 获取屏幕边距 EdgeInsets padding = context.sizes.padding; // 获取设备像素比 double pixelRatio = context.sizes.devicePixelRatio; // 使用可能为空的属性 double? maybeWidth = context.sizes.maybeWidth; return Container( width: screenWidth * 0.8, height: screenHeight * 0.5, padding: padding, child: Text( \'Device Pixel Ratio: $pixelRatio\', style: TextStyle(fontSize: 16 * context.sizes.textScaler.scale(1.0)), ), ); }}

扩展:

  • width: 屏幕宽度
  • height: 屏幕高度
  • padding: 屏幕边距
  • viewInsets: 视图插入
  • systemGestureInsets: 系统手势插入
  • viewPadding: 视图边距
  • devicePixelRatio: 设备像素比
  • textScaler: 文本缩放器
4.6 导航扩展

示例:

context.navigator.pushMaterial(NewPage());

扩展:

  • canPop: 检查是否可以弹出当前路由
  • maybePop: 尝试弹出当前路由
  • pop: 弹出当前路由
  • popUntil: 弹出路由直到满足条件
  • push: 推送新路由
  • pushMaterial: 使用 MaterialPageRoute 推送新页面
  • pushCupertino: 使用 CupertinoPageRoute 推送新页面
  • popAndPushNamed: 弹出当前路由并推送命名路由
  • pushAndRemoveUntil: 推送新路由并删除之前的路由直到满足条件
  • pushNamed: 推送命名路由
  • pushNamedAndRemoveUntil: 推送命名路由并删除之前的路由直到满足条件
  • pushReplacement: 推送新路由并替换当前路由
  • pushReplacementMaterial: 使用 MaterialPageRoute 推送新页面并替换当前路由
  • pushReplacementCupertino: 使用 CupertinoPageRoute 推送新页面并替换当前路由
  • pushReplacementNamed: 推送命名路由并替换当前路由
  • removeRoute: 移除指定路由
  • removeRouteBelow: 移除指定路由下方的路由
  • replace: 替换指定路由
  • replaceRouteBelow: 替换指定路由下方的路由
4.7 数字转内边距

示例:

// 创建所有方向上偏移量为 16 的内边距EdgeInsets padding1 = 16.paddingAll();// 创建水平方向上偏移量为 20 的内边距EdgeInsets padding2 = 20.paddingHorizontal();// 创建垂直方向上偏移量为 10 的内边距EdgeInsets padding3 = 10.paddingVertical();// 创建只有顶部偏移量为 8 的内边距EdgeInsets padding4 = 8.paddingTop();// 创建只有左侧偏移量为 12 的内边距EdgeInsets padding5 = 12.paddingLeft();// 创建只有右侧偏移量为 15 的内边距EdgeInsets padding6 = 15.paddingRight();// 创建只有底部偏移量为 5 的内边距EdgeInsets padding7 = 5.paddingBottom();

扩展:

  • paddingAll: 创建所有方向上偏移量相等的内边距
  • paddingHorizontal: 创建水平方向上对称的内边距
  • paddingVertical: 创建垂直方向上对称的内边距
  • paddingTop: 创建只有顶部内边距的 EdgeInsets
  • paddingLeft: 创建只有左侧内边距的 EdgeInsets
  • paddingRight: 创建只有右侧内边距的 EdgeInsets
  • paddingBottom: 创建只有底部内边距的 EdgeInsets
4.8 平台查询

示例:

class MyWidget extends StatelessWidget {  Widget build(BuildContext context) { if (context.isAndroid) { return Text(\'This is an Android device\'); } else if (context.isIOS) { return Text(\'This is an iOS device\'); } else if (context.isMacOS) { return Text(\'This is a MacOS device\'); } else if (context.isWindows) { return Text(\'This is a Windows device\'); } else if (context.isLinux) { return Text(\'This is a Linux device\'); } else if (context.isFuchsia) { return Text(\'This is a Fuchsia device\'); } else { return Text(\'Unknown platform\'); } }}

扩展:

  • platform: 获取当前平台
  • isAndroid: 检查当前系统是否为 Android
  • isIOS: 检查当前系统是否为 iOS
  • isMacOS: 检查当前系统是否为 MacOS
  • isWindows: 检查当前系统是否为 Windows
  • isFuchsia: 检查当前系统是否为 Fuchsia
  • isLinux: 检查当前系统是否为 Linux
4.9 数字转 SizedBox

示例:

// 创建一个宽度为 10 的水平间距SizedBox horizontalGap = 10.horizontalSpace;// 创建一个高度为 20 的垂直间距SizedBox verticalGap = 20.verticalSpace;// 在 Widget 树中使用Column( children: [ Text(\'First item\'), 10.verticalSpace, // 添加 10 单位的垂直间距 Text(\'Second item\'), 20.verticalSpace, // 添加 20 单位的垂直间距 Text(\'Third item\'), ],);Row( children: [ Text(\'Left\'), 15.horizontalSpace, // 添加 15 单位的水平间距 Text(\'Right\'), ],);

扩展:

  • horizontalSpace: 创建具有指定宽度的 SizedBox
  • verticalSpace: 创建具有指定高度的 SizedBox
4.10 字符串

示例:

// 大写转换print(\'hello world\'.capitalize()); // 输出: Hello Worldprint(\'hello world\'.capitalizeFirst()); // 输出: Hello world// 布尔值转换print(\'true\'.isBool()); // 输出: trueprint(\'false\'.toBool()); // 输出: false// 数字转换print(\'123\'.isNum()); // 输出: trueprint(\'3.14\'.toDouble()); // 输出: 3.14print(\'42\'.toInt()); // 输出: 42// 颜色转换Color color = \'FF5733\'.toColor;MaterialColor materialColor = \'FF5733\'.toMaterialColor;// 字符串处理print(\'Hello World\'.removeAllWhitespace()); // 输出: HelloWorldprint(\'abc123\'.hasMatch(r\'\\d+\')); // 输出: trueprint(\'

Hello

\'
.clearHtml); // 输出: Hello

扩展:

  • capitalize: 将每个单词的首字母大写
  • capitalizeFirst: 将字符串的第一个字母大写
  • isBool: 检查字符串是否可以转换为布尔值
  • toBool: 将字符串转换为布尔值
  • isNum: 检查字符串是否可以转换为数字
  • toNum: 将字符串转换为数字
  • isDouble: 检查字符串是否可以转换为双精度浮点数
  • toDouble: 将字符串转换为双精度浮点数
  • isInt: 检查字符串是否可以转换为整数
  • toInt: 将字符串转换为整数
  • toColor: 将十六进制颜色字符串转换为 Color 对象
  • toMaterialColor: 将十六进制颜色字符串转换为 MaterialColor 对象
  • removeAllWhitespace: 移除字符串中的所有空格
  • hasMatch: 检查字符串是否匹配指定的正则表达式模式
  • clearHtml: 移除字符串中的所有 HTML 标签
4.11 Text 文本

示例:

Text myText = Text(\'Hello, World!\');// 修改文本样式myText = myText.textStyle(TextStyle(color: Colors.blue));// 设置文本为粗体myText = myText.bold();// 设置文本为斜体myText = myText.italic();// 设置字体大小myText = myText.fontSize(18);// 设置字体系列myText = myText.fontFamily(\'Roboto\');// 添加文本阴影myText = myText.textShadow(color: Colors.grey, blurRadius: 2);// 设置文本颜色myText = myText.textColor(Colors.red);// 设置文本对齐方式myText = myText.textAlignment(TextAlign.center);// 组合多个样式myText = myText .bold() .fontSize(20) .textColor(Colors.green) .textAlignment(TextAlign.right);

扩展:

  • copyWith: 创建一个新的 Text 对象,可选择性地修改其属性
  • textStyle: 应用新的 TextStyle
  • textScale: 设置文本缩放因子
  • bold: 将文本设置为粗体
  • italic: 将文本设置为斜体
  • fontWeight: 设置文本的字体粗细
  • fontSize: 设置文本的字体大小
  • fontFamily: 设置文本的字体系列
  • letterSpacing: 设置文本的字母间距
  • wordSpacing: 设置文本的单词间距
  • textShadow: 为文本添加阴影效果
  • textElevation: 为文本添加立体效果
  • textColor: 设置文本颜色
  • textAlignment: 设置文本对齐方式
  • textDirection: 设置文本方向
  • textBaseline: 设置文本基线
  • textWidthBasis: 设置文本宽度基准
4.12 TextSpan 文本

示例:

TextSpan myTextSpan = TextSpan(text: \'Hello, World!\');// 修改文本样式myTextSpan = myTextSpan.textStyle(TextStyle(color: Colors.blue));// 设置文本为粗体myTextSpan = myTextSpan.bold();// 设置文本为斜体myTextSpan = myTextSpan.italic();// 设置字体大小myTextSpan = myTextSpan.fontSize(18);// 设置字体系列myTextSpan = myTextSpan.fontFamily(\'Roboto\');// 添加文本阴影myTextSpan = myTextSpan.textShadow(color: Colors.grey, blurRadius: 2);// 设置文本颜色myTextSpan = myTextSpan.textColor(Colors.red);// 组合多个样式myTextSpan = myTextSpan .bold() .fontSize(20) .textColor(Colors.green);

扩展:

  • copyWith: 创建一个新的 TextSpan 对象,可选择性地修改其属性
  • textStyle: 应用新的 TextStyle
  • bold: 将文本设置为粗体
  • italic: 将文本设置为斜体
  • fontWeight: 设置文本的字体粗细
  • fontSize: 设置文本的字体大小
  • fontFamily: 设置文本的字体系列
  • letterSpacing: 设置文本的字母间距
  • wordSpacing: 设置文本的单词间距
  • textShadow: 为文本添加阴影效果
  • textElevation: 为文本添加立体效果
  • textColor: 设置文本颜色
  • textBaseline: 设置文本基线

代码

https://github.com/ducafecat/flutter_package_ducafe_ui_core

小结

本文详细介绍了 Flutter 组件库 ducafe_ui_core 的功能与优势,重点强调了设计稿适配、视图层打薄和多种工具类的应用。通过使用 ducafe_ui_core,开发者能够有效提升开发效率,简化 Flutter 应用的设计与开发过程。该组件库旨在为开发者提供全面的支持,让他们在构建高质量移动应用时更加得心应手。希望本文能为您在 Flutter 开发中提供实用的参考和指导。

感谢阅读本文

如果有什么建议,请在评论中让我知道。我很乐意改进。


猫哥 APP

  • SaaS Fast
  • Flutter GetX Generator

flutter 学习路径

  • Flutter 优秀插件推荐
  • Flutter 基础篇1 - Dart 语言学习
  • Flutter 基础篇2 - 快速上手
  • Flutter 实战1 - Getx Woo 电商APP
  • Flutter 实战2 - 上架指南 Apple Store、Google Play
  • Flutter 基础篇3 - 仿微信朋友圈
  • Flutter 实战3 - 腾讯即时通讯 第一篇
  • Flutter 实战4 - 腾讯即时通讯 第二篇

© 猫哥
ducafecat.com

end