flutter架 构项目基础
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:new_learn/core/config/app_config.dart';
|
||||
|
||||
/// ============================================================
|
||||
/// 【SeedPaletteDemo】Seed 色板 —— 验证"主题 seed 是否生效"的演示页
|
||||
///
|
||||
/// 一、原理:
|
||||
/// MaterialApp 的 theme.colorSchemeSeed(来自 AppConfig.theme.seedColor)
|
||||
/// 会自动生成整套 ColorScheme(primary/secondary/tertiary/...)。
|
||||
/// 页面里【不指定颜色】的 Material 组件,颜色全部取自这套色板:
|
||||
/// FilledButton/Checkbox/Switch/Radio/进度圈/聚焦输入框 等。
|
||||
/// 所以换一个品牌(seed 不同),整页组件整体变色 —— 这就是
|
||||
/// "seed 驱动全局 Material 色板" 的直接证明。
|
||||
///
|
||||
/// 二、怎么验证:
|
||||
/// flutter run → 本页所有组件是 SkyBlue 蓝
|
||||
/// flutter run --dart-define=BRAND=chucai → 本页所有组件变 Red 红
|
||||
///
|
||||
/// 三、对比理解(对照登录页为什么不变色):
|
||||
/// 本页组件【没写死颜色】→ 跟随 seed 变;
|
||||
/// 登录页所有颜色写死 Color(0xFF3B82F6) 等 → 永远蓝色,不随主题走。
|
||||
/// ============================================================
|
||||
class SeedPaletteDemoPage extends StatefulWidget {
|
||||
const SeedPaletteDemoPage({super.key});
|
||||
|
||||
@override
|
||||
State<SeedPaletteDemoPage> createState() => _SeedPaletteDemoPageState();
|
||||
}
|
||||
|
||||
class _SeedPaletteDemoPageState extends State<SeedPaletteDemoPage> {
|
||||
final _focusController = TextEditingController();
|
||||
|
||||
bool _checked = true;
|
||||
bool _switched = true;
|
||||
int _chipSelected = 1;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// 输入框 controller 必须在 dispose 释放(防内存泄漏)
|
||||
_focusController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final brandTheme = AppConfig.theme;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Seed 色板'),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: ListView(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
children: [
|
||||
// ─── ① 当前品牌 / seed 信息卡 ───
|
||||
_sectionTitle('① 当前生效的 seed'),
|
||||
Container(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
border: Border.all(color: const Color(0xFFEEF1F5)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// seed 色块:就是 AppConfig.theme.seedColor
|
||||
Container(
|
||||
width: 56.w,
|
||||
height: 56.h,
|
||||
decoration: BoxDecoration(
|
||||
color: brandTheme.seedColor,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppConfig.appName,
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: const Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4.h),
|
||||
Text(
|
||||
'主题 ${brandTheme.name} · seed '
|
||||
'${_hex(brandTheme.seedColor)}',
|
||||
style: TextStyle(
|
||||
fontSize: 12.sp,
|
||||
color: const Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
|
||||
// ─── ② 组件区说明 ───
|
||||
_sectionTitle('② 下列组件【未写死颜色】'),
|
||||
_tipCard('它们的颜色全部取自 colorSchemeSeed 自动生成的色板。'
|
||||
'跑不同品牌包,下面所有组件整体变色。'),
|
||||
|
||||
// ─── ③ 按钮组 ───
|
||||
_sectionTitle('按钮(默认取 primary)'),
|
||||
Row(
|
||||
children: [
|
||||
FilledButton(
|
||||
onPressed: () {},
|
||||
child: const Text('FilledButton'),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
OutlinedButton(
|
||||
onPressed: () {},
|
||||
child: const Text('OutlinedButton'),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: const Text('TextButton'),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
|
||||
// ─── ④ 勾选 / 开关 / 选择标签 ───
|
||||
_sectionTitle('勾选 / 开关 / 选择标签(选中色取自 seed 色板)'),
|
||||
Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: _checked,
|
||||
onChanged: (v) => setState(() => _checked = v!),
|
||||
),
|
||||
const Text('Checkbox'),
|
||||
SizedBox(width: 24.w),
|
||||
Switch(
|
||||
value: _switched,
|
||||
onChanged: (v) => setState(() => _switched = v),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
const Text('Switch'),
|
||||
SizedBox(width: 24.w),
|
||||
ChoiceChip(
|
||||
label: const Text('选项1'),
|
||||
selected: _chipSelected == 1,
|
||||
onSelected: (_) => setState(() => _chipSelected = 1),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
ChoiceChip(
|
||||
label: const Text('选项2'),
|
||||
selected: _chipSelected == 2,
|
||||
onSelected: (_) => setState(() => _chipSelected = 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
|
||||
// ─── ⑤ 进度指示器 ───
|
||||
_sectionTitle('进度指示器(默认取 primary)'),
|
||||
Row(
|
||||
children: [
|
||||
// 注意:这里不能写 const —— .w/.h 是 ScreenUtil 扩展方法,
|
||||
// extension 方法不允许出现在 const 表达式里(const_eval_extension_method)
|
||||
SizedBox(
|
||||
width: 32.w,
|
||||
height: 32.h,
|
||||
child: const CircularProgressIndicator(strokeWidth: 3),
|
||||
),
|
||||
SizedBox(width: 20.w),
|
||||
Expanded(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4.r),
|
||||
child: const LinearProgressIndicator(value: 0.6),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
|
||||
// ─── ⑥ 聚焦输入框 ───
|
||||
_sectionTitle('聚焦输入框(边框取 primary)'),
|
||||
_tipCard('点进输入框,光标 + 聚焦边框颜色 = 当前 seed 主色。'),
|
||||
TextField(
|
||||
controller: _focusController,
|
||||
decoration: InputDecoration(
|
||||
labelText: '点击聚焦看边框颜色',
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
|
||||
// ─── ⑦ 验证提示 ───
|
||||
_sectionTitle('⑦ 怎么看到变化'),
|
||||
Container(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFE8F0FE),
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Text(
|
||||
'flutter run --dart-define=BRAND=chucai\n'
|
||||
'→ 本页所有组件变成红色系。\n\n'
|
||||
'flutter run(默认爱学蝶变)\n'
|
||||
'→ 恢复 SkyBlue 蓝色系。',
|
||||
style: TextStyle(fontSize: 13.sp, color: const Color(0xFF3B82F6)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 段落小标题
|
||||
Widget _sectionTitle(String text) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: 10.h),
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: const Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 灰色提示卡
|
||||
Widget _tipCard(String text) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(12.w),
|
||||
margin: EdgeInsets.only(bottom: 12.h),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF7F8FA),
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(fontSize: 12.sp, color: const Color(0xFF666666)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Color → #RRGGBB 显示(Flutter 3.27+ 用 toARGB32 取色值)
|
||||
String _hex(Color c) {
|
||||
final v = c.toARGB32() & 0xFFFFFF;
|
||||
return '#${v.toRadixString(16).padLeft(6, '0').toUpperCase()}';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user