Flutter 启动页白天模式改造:从“手绘耳机”到透明 PNG 资源接入
最近在做一个 AI 耳机 App 的 Welcome 启动页 UI 改造。
这个页面原本已经有一版夜间模式,而且夜间模式的布局、按钮、耳机位置和交互都已经基本定稿。因此这次改造的目标不是重新设计一个页面,而是在不破坏夜间模式的前提下,为白天模式补上一套更干净、更高级的浅蓝灰智能硬件风格。
最终目标风格大致是:
浅蓝灰背景
低饱和蓝色点缀
白色半透明质感
柔和阴影
透明白色耳机主视觉
简约高级的智能硬件产品感
一、问题背景
最开始白天模式效果并不理想,主要问题集中在几个地方:
-
耳机像是用 Flutter Widget 或 CustomPaint 临时画出来的,质感不够。
-
耳机区域出现明显的灰色或白色矩形底板。
-
背景波纹和耳机没有融合,看起来像直接贴了一张图。
-
logo 资源异常,显示出了多余画布或非目标内容。
-
页面整体只是“夜间模式换浅色皮肤”,没有智能硬件欢迎页的空气感。
一开始我以为是布局没调好,后来排查发现,核心问题并不是布局,而是资源和实现路线不对。
夜间模式可以用代码绘制出比较酷的深色霓虹效果,但白天模式想要做出透明、轻拟物、玻璃感的耳机,如果继续用 Flutter Widget 强行画,很难接近目标效果。
二、核心原则
这次改造定了几个原则:
-
夜间模式保持不变。
-
不改路由、不改登录跳转、不改按钮点击逻辑。
-
白天模式耳机不再用 Flutter 手动画。
-
白天模式耳机必须使用真正透明背景的 PNG。
-
背景和 logo 可以用 Flutter 代码绘制,避免依赖异常图片资源。
-
不用 Container、ClipRRect、Opacity、ColorFilter 去“伪装”素材问题。
也就是说,耳机必须是干净的图片资源,背景和 logo 则可以通过轻量 CustomPaint 实现。
三、素材检查
白天模式耳机素材统一放在:
assets/images/transparent_earphones.png
重新检查后的图片信息如下:
size: 1254 x 1254
mode: RGBA
has_alpha: true
transparent pixels: about 71.8%
corners alpha: 0, 0, 0, 0
这说明图片确实有 alpha 透明通道,四个角也是透明的,不会天然显示白色或灰色矩形底板。
pubspec.yaml 中使用目录方式引入资源:
flutter:
uses-material-design: true
assets:
- assets/images/
只要图片放在 assets/images/ 目录下,Flutter 就可以正常加载。
这里有一个细节需要注意:
文件名最好不要带空格,比如不要写成:
transparent_earphones .png
建议统一成:
transparent_earphones.png
避免 Flutter asset 路径出现不必要的问题。
四、一次失败尝试:用 HTML 还原视觉稿
中间也尝试过一种方式:先根据目标 UI 图片生成一份高保真的 HTML + CSS 静态页面,再参考 HTML 的结构和样式去改 Flutter。
这个方法在视觉分析阶段有一定帮助,比如可以快速拆出页面结构、颜色、字号、按钮圆角、背景装饰等。
但是实际接入 Flutter 时效果并不理想。
主要原因是 HTML 页面更多是“静态视觉还原”,而 Flutter 项目里已经有现成的夜间模式布局、主题切换、按钮交互和页面结构。如果直接按 HTML 方式迁移,很容易出现几个问题:
-
Flutter 页面比例和 HTML 设计稿不一致。
-
耳机素材仍然受到图片透明度影响。
-
背景波纹、按钮、耳机位置很难直接对应。
-
容易破坏原本已经定好的夜间模式布局。
-
最后效果更像“重新写了一个页面”,而不是在原页面上适配白天模式。
所以这个方案没有作为最终主方案,只保留了它的参考价值:
HTML 可以用来确认视觉方向,但不适合作为最终 Flutter 实现依据。
最终还是回到 Flutter 原生实现路线:夜间模式保持原样,白天模式单独做主题隔离;耳机使用真正透明 PNG;背景和 logo 用轻量绘制控制。
五、白天模式实现思路
1. 背景
白天模式背景不再强依赖 bg_wave.png 图片,而是通过 Flutter 绘制:
-
顶部浅蓝灰到白色渐变;
-
很淡的弧形波纹;
-
右上角点阵;
-
少量浅蓝小光点;
-
耳机后方淡蓝波纹;
-
底部轻微曲线装饰。
这样可以避免背景图本身带白底、灰底或被拉伸变形的问题。
白天模式的背景重点不是“蓝”,而是“淡”。
蓝色只作为局部点缀,不能铺满整个页面。
2. Logo
之前的 logo_icon.png 不是一个干净的 logo 图,而是一张展示图,里面有多个 logo、棋盘格、白底和文件名。
所以白天模式顶部 logo 不再直接使用这张异常图片,而是用 CustomPaint 画一个简洁的小图标:
-
蓝色圆点;
-
三段声波弧线;
-
小巧居中;
-
没有白底;
-
没有多余文字;
-
不会显示图片文件名或异常画布。
3. 耳机主视觉
白天模式耳机只使用透明 PNG:
Image.asset(
'assets/images/transparent_earphones.png',
)
这里有一个重点:
耳机图片外层不加背景色、不加 Card、不加白色底板、不加灰色底板。
如果图片本身是真透明,那么它就可以自然悬浮在浅蓝灰背景和波纹之上。
如果图片本身不透明,再怎么用 Flutter 包 Container、ClipRRect、Opacity,都只是掩盖问题,最后一定会出现矩形底板或者发灰的问题。
六、页面结构
白天模式 Welcome 页仍保持原来的结构:
顶部小 logo
OUCCL
Welcome
短横线
Smart listening.
Beautifully connected.
耳机主视觉
Get Started
Sign in
没有新增功能模块,也没有修改交互逻辑。
Get Started 仍然负责进入主流程,Sign in 仍然作为次级登录入口。
七、关键代码方向
耳机区域的实现思路大致如下:
Stack(
alignment: Alignment.center,
children: [
Positioned.fill(
child: CustomPaint(
painter: _LightHeroWavePainter(...),
),
),
Image.asset(
'assets/images/transparent_earphones.png',
width: earphoneImageWidth,
height: earphoneImageHeight,
fit: BoxFit.fill,
),
],
)
这里没有强制保持图片原始等比例。
原因是这个耳机图本身有较大的透明留白,如果完全使用 BoxFit.contain,在页面里的视觉大小可能会偏小。实际处理时,可以在白天模式下单独设置耳机图片的显示宽高,让它在视觉上接近目标效果即可。
但需要注意:
可以轻微非等比缩放;
不要拉伸到明显变形;
不要裁切;
不要加背景容器;
不要出现矩形底板;
只在 light mode 下生效。
夜间模式仍然保留原来的耳机绘制方式,不受白天模式影响。
八、按钮和文字处理
白天模式的文字颜色主要分三层:
主标题:深蓝黑
副标题:灰蓝色
按钮文字:白色
例如:
-
OUCCL使用深蓝黑,字距略大; -
Welcome使用深蓝黑,字重较高; -
Smart listening. Beautifully connected.使用灰蓝色; -
短横线使用浅蓝渐变;
-
Get Started使用柔和亮蓝胶囊按钮; -
Sign in使用蓝色文字和小箭头。
按钮不能过于科技蓝,也不能发光太重。
整体还是要保持浅蓝灰、干净、轻盈的智能硬件风格。
九、light / dark 隔离
这次改造中最重要的一点是:
白天模式和夜间模式必须隔离。
夜间模式已经定稿,所以不能因为白天模式改造影响原来的夜间效果。
实现上可以通过 isLight 判断:
if (isLight) {
// 白天模式:使用透明 PNG 耳机 + 浅蓝灰背景
} else {
// 夜间模式:继续使用原来的深色霓虹效果
}
需要特别避免:
-
把白天模式耳机影响到夜间模式。
-
把白天模式背景渐变影响到夜间模式。
-
改动
Get Started和Sign in的跳转逻辑。 -
为了还原白天模式而重构整个页面。
本次改造应该是“在原页面上适配白天主题”,而不是重新写一个 Welcome 页。
十、最终效果目标
最终白天模式的目标是:
-
浅蓝灰白色渐变背景;
-
干净、轻盈、柔和;
-
透明白色耳机自然悬浮;
-
淡蓝波纹和点阵作为装饰;
-
深蓝黑文字;
-
灰蓝色标语;
-
柔和蓝色胶囊按钮;
-
Sign in作为蓝色次级入口。
整体方向是智能硬件产品欢迎页,而不是普通白底页面,也不是夜间模式的浅色换皮。
十一、经验总结
这次最大的教训是:
UI 效果差,不一定是代码布局的问题。
如果素材本身不合格,后面再怎么调布局和颜色,效果都很难好。
尤其是透明耳机这种主视觉,如果素材不是透明 PNG,就很容易出现:
白色矩形底板
灰色背景块
图片像直接贴上去
背景和主体不融合
正确做法应该是:
-
先检查素材是否合格。
-
图片该透明就必须真的透明。
-
背景装饰尽量独立绘制,或者使用真正透明纹理。
-
不要用代码强行修坏素材。
-
夜间模式已定稿时,白天模式要严格隔离实现。
-
HTML 可以辅助分析视觉,但不应直接决定 Flutter 的最终实现方式。
这次改造后,白天模式 Welcome 页的实现路线更清晰:
耳机用透明 PNG;
背景和 logo 用轻量绘制;
颜色通过主题隔离;
布局和交互保持原有逻辑;
夜间模式不受影响。
这样既能接近目标视觉效果,也能减少对原有代码和夜间模式的破坏。
更多推荐


所有评论(0)