3.4 一套观感、两端气质:主题与双平台适配


3.4 一套观感、两端气质:主题与双平台适配

本节摘要:自绘带来逐像素一致,也带来一个问题:界面要不要"在 iPhone 上像 iOS"?本节讲透 ThemeData 的发号机制与主题继承,搭出轻记账的明暗双主题,再给出 Material 与 Cupertino 的适配决策表——哪些组件随平台换形态、哪些坚持品牌统一、哪些直接用自适应构造器。主题系统是第 1 章"自绘流派观感可控"承诺的兑现处。

主题即配置中心:ThemeData 的发号机制

第 1 章说过自绘流派的红利是观感统一,其实现机制就是主题系统:在 MaterialApp 里发一份 ThemeData,整棵 Widget 树按需领取。底层是第 2 章讲过的 InheritedWidget——Theme.of(context) 沿 Element 树向上找到最近的主题,主题一换,所有领取者自动重建。你在任何深层组件里写的 Theme.of(context).colorScheme.primary,读的都是这份中央配置。

这份机制给出两条工程纪律。第一,颜色与字号永不写死:金额用 colorScheme.primary,错误提示用 colorScheme.error,标题字号用 textTheme——明暗主题切换、将来换品牌色,都是改一处配置的事。第二,局部主题用子树覆盖:某块区域要换配色,套一个 Theme 包住子树即可,不必逐个组件传参。

轻记账的主题配置(Material 3 风格):

ColorScheme _scheme(Brightness brightness) => ColorScheme.fromSeed( seedColor: const Color(0xFF00897B), // 品牌主色:青绿 brightness: brightness, ); MaterialApp( theme: ThemeData(useMaterial3: true, colorScheme: _scheme(Brightness.light)), darkTheme: ThemeData(useMaterial3: true, colorScheme: _scheme(Brightness.dark)), themeMode: ThemeMode.system, // 跟随系统明暗 )

ColorScheme.fromSeed 从一个种子色推算出整套配色(主色、容器色、表面色各一串),是 Material 3 的核心便利——轻记账只定了青绿一个品牌色,整套界面配色自动和谐。深色主题不用逐色手调,同一个种子色在暗亮度下重新推算即可。themeMode 设为 system,应用观感跟随系统昼夜切换,深夜记账不刺眼。

图 8 一份代码的两种气质:同一界面的双平台形态

图 8 一份代码的两种气质:同一界面的双平台形态

要不要"在 iPhone 上像 iOS"

自绘是把双刃剑:统一是红利,"不像那个平台"也是代价。iOS 用户对手感有一套肌肉记忆——页面从右缘推入、列表带弹簧回弹、按钮按压是变亮而非水波纹。轻记账的决策过程给出一份可复用的判断表:

界面元素 决策 理由
导航转场与滑动返回 随平台(CupertinoPageRoute) 肌肉记忆最顽固的地方,逆着做必被吐槽
按钮、对话框、菜单 随平台(自适应构造器) 观感差异大、实现成本低
列表滚动质感 随平台(ScrollPhysics 默认已分端) 框架默认行为已正确,别去覆盖
品牌色、字体、图表 认品牌 跨平台一致性是产品识别度的一部分
页面布局结构 认品牌 两套布局成本翻倍,收益有限

落地上不必手写 if 判断平台再选组件——Flutter 提供了自适应构造器,一行完成分端:

Switch.adaptive(value: _autoSync, onChanged: _toggle), // iOS 出 Cupertino 开关 SwitchListTile.adaptive(title: const Text('自动同步'), value: _autoSync, onChanged: _toggle), Slider.adaptive(value: _budget, onChanged: _setBudget), IconButton.filledTonal( onPressed: () => showAdaptiveDialog( context: context, builder: (_) => const BudgetEditDialog(), ), icon: const Icon(Icons.tune), ),

路由的分端在 MaterialApp 里配一次即可:iOS 用 Cupertino 风格转场,其余用 Material 默认——

MaterialApp( theme: ThemeData(useMaterial3: true, colorScheme: _scheme(Brightness.light)), pageTransitionsTheme: const PageTransitionsTheme(builders: { TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), // 右缘推入与滑动返回 TargetPlatform.android: ZoomPageTransitionsBuilder(), }), )

需要更彻底的 iOS 形态(整套 Cupertino 导航栈、毛玻璃底栏)时,再引入 cupertino 库逐页替换——但先想清楚值不值:每页两套形态意味着每页两套视觉回归测试。轻记账最终只对"账单详情"一个高频页面做了完整 Cupertino 形态,其余页面用自适应构造器与分端转场过渡,两端用户的主观评测都通过了。适配深度跟着用户感知走,不跟工程师的强迫症走。

本节要点回顾

  • Theme 是中央配置:ThemeData 在根部发号,Theme.of 沿树领取,换主题即换全部;
  • ColorScheme.fromSeed 一个种子色推全套配色,明暗两份主题一份品牌色;
  • 颜色字号永不写死,局部差异用 Theme 子树覆盖;
  • 适配决策表:导航手感随平台、品牌识别认品牌、布局结构不双份;
  • 自适应构造器(Switch.adaptive 等)与分端转场主题,是性价比最高的两端适配手段。

标准组件画不出的视觉——统计页的占比图——下一节用 CustomPaint 亲手画。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U