ecp_theme 2.1.0
ecp_theme: ^2.1.0 copied to clipboard
翼协云主题管理包,提供 Light/Dark 主题配置、Color/Theme 扩展、通用尺寸规范及文本组件封装,内部项目通用的 Flutter 主题工具库。
import 'package:device_preview/device_preview.dart';
import 'package:ecp_theme/ecp_theme.dart';
import 'package:example/pages/color_ext_page.dart';
import 'package:example/pages/color_page.dart';
import 'package:example/pages/defalut_test_page.dart';
import 'package:example/pages/text_style_page.dart';
import 'package:example/pages/theme_switch_page.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'pages/color_scheme_page.dart';
void main() {
runApp(
DevicePreview(
builder: (context) => const MyApp(),
enabled: true,
),
);
}
/// App 级主题模式(theme_switch_page 中的开关修改它)
final ValueNotifier<ThemeMode> appThemeMode =
ValueNotifier<ThemeMode>(ThemeMode.light);
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: Dimens.designSize,
useInheritedMediaQuery: !kReleaseMode,
builder: (context, widget) {
var child = ValueListenableBuilder<ThemeMode>(
valueListenable: appThemeMode,
builder: (context, mode, _) => MaterialApp(
title: '翼协云主题示例',
theme: Themes.light,
darkTheme: Themes.dark,
themeMode: mode,
home: const HomePage(),
),
);
return DevicePreview.appBuilder(context, child);
},
);
}
}
/// 演示项数据
class _Demo {
final IconData icon;
final String title;
final String subtitle;
final WidgetBuilder builder;
const _Demo(this.icon, this.title, this.subtitle, this.builder);
}
final List<_Demo> _demos = [
_Demo(Icons.palette_outlined, '主题颜色', 'Themes 内置色板与辅助色', (_) => const ColorPage()),
_Demo(Icons.colorize_outlined, 'ColorScheme', 'Material 3 色彩方案', (_) => const ColorSchemePage()),
_Demo(Icons.invert_colors_outlined, '颜色扩展', 'ColorExt 加深提亮/明暗判断', (_) => const ColorExtPage()),
_Demo(Icons.text_fields_outlined, '字体样式', 'TextStyles 与文本组件', (_) => const TextStylePage()),
_Demo(Icons.dark_mode_outlined, '主题切换', 'Light/Dark 联动演示', (_) => const ThemeSwitchPage()),
_Demo(Icons.sentiment_dissatisfied_outlined, '缺省页', 'DefaultPage 占位视图', (_) => const DefaultTestPage()),
];
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('翼协云主题示例')),
body: GridView.builder(
padding: EdgeInsets.all(Dimens.listHorizontalPadding),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 220,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: 1.05,
),
itemCount: _demos.length,
itemBuilder: (context, index) {
var demo = _demos[index];
return _DemoCard(demo: demo);
},
),
);
}
}
class _DemoCard extends StatelessWidget {
const _DemoCard({required this.demo});
final _Demo demo;
@override
Widget build(BuildContext context) {
var scheme = context.colorScheme;
return Card(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: scheme.outlineVariant.withValues(alpha: 0.4)),
),
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(builder: demo.builder)),
child: Padding(
padding: const EdgeInsets.all(14),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: scheme.primaryContainer.withValues(alpha: 0.55),
shape: BoxShape.circle,
),
child: Icon(demo.icon, size: 28, color: scheme.primary),
),
const SizedBox(height: 10),
TextTitles.small(context, demo.title),
const SizedBox(height: 4),
TextBodies.small(
context,
demo.subtitle,
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
),
);
}
}