【Flutter for OpenHarmony】flutter_launcher_icons 应用图标与启动画面的鸿蒙化适配与实战指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net


一、为什么应用图标这么重要?

我是 IntMainJhy,上海某高校大一计算机专业的学生。说起应用图标,我一开始完全没当回事。

我的第一版 App 图标就是用 Flutter 默认的图标,结果室友看了说:“你这 App 图标怎么跟别人一模一样?这也太敷衍了吧?”

后来我才明白,应用图标是用户第一眼看到的东西,它代表了 App 的品牌形象。一个好的图标可以让用户记住你的 App,一个丑的图标可能让用户连下载的欲望都没有。


二、flutter_launcher_icons 介绍

2.1 什么是 flutter_launcher_icons?

flutter_launcher_icons 是一个自动生成多平台应用图标的库:

# pubspec.yaml
dev_dependencies:
  flutter_launcher_icons: ^0.14.1

2.2 支持的平台

平台 图标类型
Android mipmap, adaptive
iOS AppIcon
OpenHarmony mipmap
Web favicon
macOS icns
Windows ico

三、项目配置

3.1 pubspec.yaml

dev_dependencies:
  flutter_launcher_icons: ^0.14.1

flutter_launcher_icons:
  android: true
  ios: true
  ohos: true  # OpenHarmony 支持
  web: true
  image_path: "assets/icons/icon.png"
  image_path_android: "assets/icons/icon_android.png"
  image_path_ios: "assets/icons/icon_ios.png"
  adaptive_icon_background: "#6C63FF"
  adaptive_icon_foreground: "assets/icons/icon_foreground.png"

3.2 图标设计规范

assets/icons/
├── icon.png              # 基础图标 (1024x1024)
├── icon_android.png     # Android 专用 (1024x1024)
├── icon_ios.png         # iOS 专用 (1024x1024)
├── icon_foreground.png   # 自适应图标前景 (432x432)
└── icon_background.png   # 自适应图标背景 (432x432)

四、生成图标

4.1 准备图标文件

图标设计要求:

  • 基础图标:1024x1024 像素
  • 格式:PNG(支持透明度)
  • 内容:简洁、有辨识度

4.2 生成命令

# 进入项目目录
cd my_ohos_app

# 运行图标生成
flutter pub run flutter_launcher_icons

4.3 生成结果

android/app/src/main/res/
├── mipmap-hdpi/
│   └── ic_launcher.png       # 72x72
├── mipmap-mdpi/
│   └── ic_launcher.png       # 48x48
├── mipmap-xhdpi/
│   └── ic_launcher.png       # 96x96
├── mipmap-xxhdpi/
│   └── ic_launcher.png       # 144x144
├── mipmap-xxxhdpi/
│   └── ic_launcher.png       # 192x192
└── drawable/
    └── ic_launcher_background.xml  # 背景

五、OpenHarmony 图标配置

5.1 鸿蒙图标目录

ohos/entry/src/main/res/
├── base/
│   └── media/
│       ├── app_icon.png        # 应用图标
│       └── ic_launcher.png    # 启动器图标
└── rawfile/                    # 原始文件

5.2 手动配置鸿蒙图标

如果 flutter_launcher_icons 没有自动生成鸿蒙图标,需要手动配置:

// ohos/entry/src/main/module.json5
{
  "module": {
    "icon": "$media:app_icon",
    "label": "$string:entry_ModuleAbility_label"
  }
}

5.3 图标资源配置

{
  "resources": {
    "media": [
      {
        "name": "app_icon",
        "type": "bitmap"
      }
    ]
  }
}

六、启动画面配置

6.1 Android 启动画面

<!-- android/app/src/main/res/drawable/launch_background.xml -->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/launch_background_color" />
    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher" />
    </item>
</layer-list>
<!-- android/app/src/main/res/values/colors.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="launch_background_color">#6C63FF</color>
</resources>

6.2 OpenHarmony 启动画面

// ohos/entry/src/main/resources/base/element/color.json
{
  "color": [
    {
      "name": "start_window_background",
      "value": "#6C63FF"
    }
  ]
}

6.3 启动画面主题

<!-- android/app/src/main/res/values/styles.xml -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
    <item name="android:windowBackground">@drawable/launch_background</item>
</style>

七、自定义启动动画

7.1 Flutter 启动动画组件

// lib/mental_health/widgets/splash_screen.dart

import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';

/// 启动画面
class SplashScreen extends StatefulWidget {
  final VoidCallback onComplete;

  const SplashScreen({
    super.key,
    required this.onComplete,
  });

  
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  
  void initState() {
    super.initState();
    // 延迟 2 秒后进入主页
    Future.delayed(const Duration(seconds: 2), () {
      widget.onComplete();
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF6C63FF),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // Logo
            Container(
              width: 120,
              height: 120,
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(30),
                boxShadow: [
                  BoxShadow(
                    color: Colors.black.withOpacity(0.2),
                    blurRadius: 20,
                    offset: const Offset(0, 10),
                  ),
                ],
              ),
              child: const Icon(
                Icons.favorite,
                size: 60,
                color: Color(0xFF6C63FF),
              ),
            )
                .animate()
                .scale(
                  begin: const Offset(0.5, 0.5),
                  end: const Offset(1.0, 1.0),
                  duration: 600.ms,
                  curve: Curves.easeOutBack,
                )
                .fadeIn(duration: 300.ms),

            const SizedBox(height: 32),

            // App 名称
            const Text(
              '心理健康',
              style: TextStyle(
                fontSize: 32,
                fontWeight: FontWeight.bold,
                color: Colors.white,
              ),
            )
                .animate()
                .fadeIn(delay: 300.ms, duration: 400.ms)
                .slideY(begin: 0.3, end: 0),

            const SizedBox(height: 8),

            // 副标题
            const Text(
              '关注内心,拥抱生活',
              style: TextStyle(
                fontSize: 16,
                color: Colors.white70,
              ),
            )
                .animate()
                .fadeIn(delay: 500.ms, duration: 400.ms),

            const SizedBox(height: 60),

            // 加载指示器
            const CircularProgressIndicator(
              valueColor: AlwaysStoppedAnimation(Colors.white),
              strokeWidth: 2,
            )
                .animate()
                .fadeIn(delay: 700.ms, duration: 300.ms),
          ],
        ),
      ),
    );
  }
}

7.2 在应用中使用启动画面

// main.dart

void main() {
  runApp(const MentalHealthApp());
}

class MentalHealthApp extends StatefulWidget {
  const MentalHealthApp({super.key});

  
  State<MentalHealthApp> createState() => _MentalHealthAppState();
}

class _MentalHealthAppState extends State<MentalHealthApp> {
  bool _showSplash = true;

  void _onSplashComplete() {
    setState(() {
      _showSplash = false;
    });
  }

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '心理健康',
      debugShowCheckedModeBanner: false,
      theme: AppTheme.lightTheme,
      home: _showSplash
          ? SplashScreen(onComplete: _onSplashComplete)
          : const MentalHealthHomeScreen(),
    );
  }
}

八、OpenHarmony 适配

8.1 鸿蒙图标路径

鸿蒙设备的图标路径和 Android 不同:

ohos/entry/src/main/resources/
├── base/
│   └── media/
│       ├── app_icon.png      # 主图标
│       └── ic_launcher.png   # 启动图标
└── rawfile/

8.2 手动复制图标

# 将生成的图标复制到鸿蒙目录
cp android/app/src/main/res/mipmap-hdpi/ic_launcher.png \
   ohos/entry/src/main/resources/base/media/ic_launcher.png

九、我的踩坑记录

坑1:图标生成失败

报错:找不到图标文件。

原因:图标路径配置错误。

解决

# 确保路径正确
image_path: "assets/icons/icon.png"

坑2:OpenHarmony 图标不显示

问题:鸿蒙设备上图标是默认的。

原因:没有手动配置鸿蒙图标。

解决:手动复制图标到鸿蒙目录。


坑3:自适应图标背景色不对

问题:自适应图标背景不是紫色。

解决

flutter_launcher_icons:
  adaptive_icon_background: "#6C63FF"  # 使用正确的颜色值

十、功能验证清单

序号 检查项 测试设备 预期结果
1 Android 图标 Android 手机 正确显示
2 iOS 图标 iPhone 正确显示
3 鸿蒙图标 鸿蒙设备 正确显示
4 启动画面 所有设备 正常显示
5 自适应图标 Android 8+ 正常显示

十一、大一学生真实学习总结

图标和启动画面是 App 的"门面",虽然不是核心功能,但非常重要。

最重要的几点:

  1. 图标要简洁

    • 不要放太多细节
    • 要在各种尺寸下都清晰可见
  2. 启动画面要快

    • 不要让用户等太久
    • 2-3 秒最合适
  3. 品牌色要统一

    • 图标和 App 主题色要一致
    • 建立品牌认知
  4. 多平台适配

    • 不同平台图标要求不同
    • 要分别测试

作者:IntMainJhy
创作时间:2026年5月
在这里插入图片描述
在这里插入图片描述

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐