yuni_widget 0.1.5
yuni_widget: ^0.1.5 copied to clipboard
Yu Ni widget library for common UI components and theme configuration
yuni_widget #
yuni_widget 是一个基于 Flutter 的通用 UI 组件库和主题配置系统。它提供了一套完整的、可定制的设计规范实现,旨在帮助开发者快速构建风格统一、美观的跨平台应用。
📚 项目介绍 #
定位 #
yuni_widget 定位为 Flutter 应用的 UI 基础设施。它不仅仅是一组 UI 控件的集合,更是一套包含了颜色、字体、间距、圆角等设计系统的完整解决方案。
解决的问题 #
- 样式不统一:解决项目中颜色、字体、间距随意硬编码导致的视觉不一致问题。
- 重复造轮子:内置常用的 Toast、Dialog、Loading、Button 等组件,避免重复开发。
- 主题管理困难:提供统一的主题配置入口,支持一键切换亮色/暗色模式,支持动态下发主题配置(JSON)。
- 开发效率:通过语义化的组件命名(如
YText.headingLarge),减少样式代码编写,提升开发效率。
优点 #
- 配置灵活:支持全局配置主题色、圆角、字体等,一处修改,全局生效。
- 组件丰富:覆盖了从基础的 Text、Button 到复杂的 Dialog、BottomSheet、Input 等常用组件。
- 更佳的开发体验:高度封装的 API,语义化的样式定义,让代码更易读、易维护。
- 开箱即用:默认提供了一套美观的亮色/暗色主题,无需配置即可使用。
🚀 初始化 #
在使用组件之前,建议在应用入口处进行初始化,以覆盖默认的样式逻辑。
1. 基础初始化 #
在 main.dart 或应用启动逻辑中初始化配置:
import 'package:yuni_widget/yuni_widget.dart';
void main() {
// 初始化配置 (可选)
// 如果不进行初始化,将使用默认的 Light 主题
YuniWidgetConfig.instance.init(
// 自定义主色调
primaryColor: Colors.blue,
// 或者完全自定义所有颜色
// colors: AppColors(...),
// 自定义字体
fontFamily: 'Roboto',
// 默认主题模式
brightness: Brightness.light,
);
runApp(const MyApp());
}
2. 接入 MaterialApp #
将 YuniWidgetConfig 生成的 ThemeData 传递给 MaterialApp,使标准 Flutter 组件也能适配主题:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Yuni Widget Demo',
// 使用配置生成的主题
theme: YuniWidgetConfig.instance.toThemeData(),
home: const MyHomePage(),
);
}
}
3. 使用 YuNiBaseWidget (可选) #
推荐在页面根节点或需要获得全局 Key 上下文的地方使用 YuNiBaseWidget:
@override
Widget build(BuildContext context) {
return YuNiBaseWidget(
child: Scaffold(
// ...
),
);
}
🧩 支持的组件 #
yuni_widget 提供了丰富的内置组件:
| 类别 | 组件名 | 描述 |
|---|---|---|
| 基础/排版 | YText |
统一文本组件,支持 Display/Heading/Body/Label 等多种语义化样式 |
YDivider |
分隔线,支持自定义颜色、虚线/实线、粗细及间距 | |
YSpacing |
标准化间距组件,用于快速添加垂直或水平空白 | |
YuNiBaseWidget |
根组件,用于提供全局 Key 和基础配置上下文 | |
| 按钮与点击 | YButton |
通用按钮,支持主/次/文字按钮及各种尺寸配置 |
YTapped |
点击容器,封装了点击水波纹、缩放效果及事件防抖 | |
| 表单输入 | YInput |
标准输入框,支持装饰器、验证错误显示 |
YComboInput |
组合输入组件,适用于选择器、日期选择等非纯文本输入场景 | |
YRadio |
单选框组件 | |
YToggleSwitch |
开关切换组件 | |
| 反馈与提示 | YToast |
消息提示组件 |
YToastHelper |
Toast 工具类,快速显示成功、失败、警告消息 | |
YDialog |
基础对话框组件 | |
YDialogHelper |
对话框工具类,快速调用确认框、输入框等 | |
YLoading |
局部加载指示器 | |
YLoadingDialog |
全局加载弹窗 | |
YLoadingDialogHelper |
加载弹窗工具类,支持自动定时关闭 | |
| 导航与菜单 | YAppBar |
统一风格的顶部应用栏 |
ContextMenuArea |
上下文菜单触发区域(支持右键/长按) | |
ContextMenuItem |
上下文菜单的子选项 | |
YBottomSheet |
底部弹出面板组件 | |
BottomSheetHelp |
底部面板工具类,快速唤起底部列表或自定义视图 | |
SheetTextItemWidget |
底部面板中的标准文本列表项 |
📖 如何使用 #
1. 文本 (YText) #
不再需要手动编写 TextStyle,使用语义化的构造函数:
// 大标题
YText.displayLarge("Display Large");
// 正文
YText.bodyMediumRegular("这是正文内容");
// 标签
YText.labelSmallBold("TAG", color: Colors.blue);
// 普通使用
YText("自定义样式", style: TextStyle(fontSize: 20));
2. 按钮 (YButton) #
// 主按钮
YButton.primary(
text: "确认提交",
onTap: () {
print("Clicked");
},
);
// 次要按钮
YButton.secondary(
text: "取消",
onTap: () => Navigator.pop(context),
);
// 禁用状态
YButton.primary(
text: "不可点击",
enable: false,
onTap: () {},
);
3. 弹窗与提示 (Toast & Dialog) #
// 显示 Toast
YToast.show(context, "操作成功", type: YToastType.success);
// 显示 Loading
YLoadingDialog.show(context);
// 2秒后关闭
Future.delayed(Duration(seconds: 2), () {
YLoadingDialog.dismiss(context);
});
// 显示确认对话框
YDialogHelper.showConfirmDialog(
context,
title: "提示",
content: "确定要删除这条记录吗?",
onConfirm: () {
// 执行删除逻辑
},
);
4. 输入框 (YInput) #
YInput(
hintText: "请输入用户名",
prefixIcon: Icon(Icons.person),
onChanged: (value) {
// ...
},
);
🛠 如何拓展 #
如果内置组件无法满足需求,你可以利用 YuniWidgetConfig 中的主题配置来构建自定义组件,从而保持设计风格的一致性。
1. 访问主题配置 #
通过 YuniWidgetConfig.instance 可以访问所有的设计 Token:
final config = YuniWidgetConfig.instance;
// 颜色
Color primary = config.colors.primary;
Color bg = config.colors.background;
// 字体
TextStyle heading = config.textStyles.headingMediumTS;
// 间距
double spacing = config.spacing.md;
// 圆角
BorderRadius radius = config.radius.borderMd;
2. 自定义组件示例 #
编写一个自定义的卡片组件:
class MyCustomCard extends StatelessWidget {
final Widget child;
const MyCustomCard({super.key, required this.child});
@override
Widget build(BuildContext context) {
final colors = YuniWidgetConfig.instance.colors;
final radius = YuniWidgetConfig.instance.radius;
final spacing = YuniWidgetConfig.instance.spacing;
return Container(
padding: EdgeInsets.all(spacing.md), // 使用统一间距
decoration: BoxDecoration(
color: colors.surface, // 使用统一背景色
borderRadius: radius.borderMd, // 使用统一圆角
boxShadow: [
BoxShadow(
color: colors.shadow.withOpacity(0.1),
blurRadius: 10,
)
],
),
child: child,
);
}
}
🎨 主题切换 #
支持运行时的动态主题切换:
// 切换到暗色模式
YuniWidgetConfig.instance.setDarkMode();
// 切换到亮色模式
YuniWidgetConfig.instance.setLightMode();
// 自动切换
YuniWidgetConfig.instance.toggleThemeMode();
需要注意的是,切换主题后,需要确保根部的 MaterialApp 或者依赖主题的组件能够重建(Rebuild),通常结合状态管理工具(如 Provider, Bloc, GetX 等)使用来触发全局更新。