Flutter应用图标更改插件flutter_app_icon_changer的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter应用图标更改插件flutter_app_icon_changer的使用

Description

本项目展示了如何在Flutter应用程序中实现Android和iOS平台上的应用图标更改功能。

Android iOS
Android demo iOS demo

Getting Started

要开始使用这些示例,请克隆仓库并导航到项目目录:

git clone https://github.com/Innim/flutter_app_icon_changer.git
cd flutter_app_icon_changer

Setup

Adding Assets to pubspec.yaml

确保在pubspec.yaml文件中正确声明您的图标资源,以便它们可以在您的Flutter应用程序中使用。

flutter:
  assets:
    - assets/icons/

Setup Android

要在您的Android应用程序中启用更改应用图标的功能,请按照以下步骤操作:

  1. 修改AndroidManifest.xml:

    打开文件android/app/src/main/AndroidManifest.xml并添加以下内容:

    <!-- Main Activity -->
    <activity
        android:name=".MainActivity"
        android:exported="true"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize">
        <meta-data
            android:name="io.flutter.embedding.android.NormalTheme"
            android:resource="@style/NormalTheme"
        />
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    
    <!-- Alternate Icon 1 -->
    <activity-alias
        android:name=".MainActivityAlias1"
        android:enabled="false"
        android:exported="true"
        android:icon="@mipmap/ic_launcher1"
        android:targetActivity=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    
    <!-- Alternate Icon 2 -->
    <activity-alias
        android:name=".MainActivityAlias2"
        android:enabled="false"
        android:exported="true"
        android:icon="@mipmap/ic_launcher2"
        android:targetActivity=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    

    解释:

    • .MainActivityAlias1.MainActivityAlias2 是用于切换图标的活动别名。
    • android:icon 指定了要显示的图标资源。
    • android:enabled="false" 表示别名默认禁用,并将在更改图标时通过编程启用。
  2. 添加替换图标:

    android/app/src/main/res/mipmap- 文件夹中创建新的图标文件,命名为 ic_launcher1.pngic_launcher2.png。这些名称应与 android:icon 中的值匹配。

    示例文件夹结构:

    android/app/src/main/res/
        mipmap-mdpi/
            ic_launcher.png
            ic_launcher1.png
            ic_launcher2.png
        mipmap-hdpi/
            ic_launcher.png
            ic_launcher1.png
            ic_launcher2.png
        ...
    

    提示:

    • 确保图标尺寸适合每个屏幕密度。
    • 您可以使用图标生成器简化此过程。
  3. 更新 build.gradle (如果需要):

    确保在 android/app/build.gradle 文件中的最小SDK版本设置为21或更高:

    defaultConfig {
        applicationId "com.example.flutter_app_icon_changer"
        minSdkVersion 21
        targetSdkVersion 33
        // ...
    }
    
  4. 清理并重新构建项目:

    完成上述更改后,运行以下命令:

    flutter clean
    flutter pub get
    flutter run
    

Setup iOS

要在您的iOS应用程序中启用更改应用图标的功能,请按照以下步骤操作:

  1. 将替换图标添加到资源中:

    在Xcode中打开项目:

    open ios/Runner.xcworkspace
    

    在Xcode中:

    • 导航到 Runner/Assets.xcassets
    • 右键单击并选择 New App Icon 添加每个替换图标。
    • 将新应用图标命名为与Info.plist中指定的完全一致(例如,AppIcon1, AppIcon2)。
    • 向每个应用图标集添加适当大小的图标图像。 重要: 图标必须是AppIcon类型(应用图标集),而不是普通图像集。
  2. 修改Info.plist:

    打开文件 ios/Runner/Info.plist 并在 CFBundleIcons 下添加替换图标:

    <key>CFBundleIcons</key>
    <dict>
        <key>CFBundlePrimaryIcon</key>
        <dict>
            <key>CFBundleIconFiles</key>
            <array>
                <string>AppIcon</string>
            </array>
        </dict>
        <key>CFBundleAlternateIcons</key>
        <dict>
            <key>Icon1</key>
            <dict>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>AppIcon1</string>
                </array>
            </dict>
            <key>Icon2</key>
            <dict>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>AppIcon2</string>
                </array>
            </dict>
        </dict>
    </dict>
    

    解释:

    • CFBundlePrimaryIcon 定义了默认的应用图标(AppIcon)。
    • CFBundleAlternateIcons 包含一个包含替换图标的字典。
    • Icon1Icon2 是在代码中使用的替换图标标识符。
    • CFBundleIconFiles 包含一个对应于Assets.xcassets中的集合的图标名称数组。
  3. 确保命名一致性:

    确保Info.plist中的名称与Assets.xcassets中的图标集名称完全一致。

  4. 重新构建项目:

    完成更改后,运行以下命令:

    flutter clean
    flutter pub get
    flutter run
    

Usage

在完成平台设置后,您可以在Flutter应用程序中使用图标更改功能。

示例用法

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

import 'package:flutter/services.dart';
import 'package:flutter_app_icon_changer/flutter_app_icon_changer.dart';
import 'package:flutter_app_icon_changer_example/src/models/models.dart';

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

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _flutterAppIconChangerPlugin = FlutterAppIconChangerPlugin(
    iconsSet: CustomIcons.list,
  );

  CustomIcon _currentIcon = CustomIcons.defaultIcon;
  var _isSupported = false;

  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
  }

  Future<void> initPlatformState() async {
    _isSupported = await _flutterAppIconChangerPlugin.isSupported();
    if (_isSupported) {
      final currentIcon = await _flutterAppIconChangerPlugin.getCurrentIcon();

      if (!mounted) return;

      setState(() {
        _currentIcon = CustomIcon.fromString(currentIcon);
      });
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('图标更改示例'),
        ),
        body: Column(
          children: <Widget>[
            const Spacer(),
            if (!_isSupported) ...[
              const Text('更改图标在此设备上不受支持'),
              const SizedBox(height: 8),
            ],
            FittedBox(
              child: Opacity(
                opacity: _isSupported ? 1 : .5,
                child: Padding(
                  padding:
                      const EdgeInsetsDirectional.symmetric(horizontal: 24),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      _buildIcon(CustomIcons.redIcon),
                      const SizedBox(width: 8),
                      _buildIcon(CustomIcons.purpleIcon),
                      const SizedBox(width: 8),
                      _buildIcon(CustomIcons.defaultIcon),
                    ],
                  ),
                ),
              ),
            ),
            const Spacer(),
          ],
        ),
      ),
    );
  }

  Widget _buildIcon(CustomIcon icon) {
    final border = BorderRadius.circular(8.0);

    return InkWell(
      borderRadius: border,
      onTap: _isSupported ? () => _changeIcon(icon) : null,
      child: Card(
        shape: icon == _currentIcon ? _buildBorder(border) : null,
        child: Padding(
          padding: const EdgeInsets.all(4.0),
          child: _buildPreviewIcon(
            icon,
          ),
        ),
      ),
    );
  }

  OutlinedBorder _buildBorder(BorderRadius borderRadius) {
    return RoundedRectangleBorder(
      borderRadius: borderRadius,
      side: BorderSide(
        color: Theme.of(context).primaryColor,
        width: 4.0,
      ),
    );
  }

  Widget _buildPreviewIcon(CustomIcon icon, {double size = 100}) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(8),
      child: Image.asset(
        icon.previewPath,
        fit: BoxFit.contain,
        width: size,
        height: size,
      ),
    );
  }

  Future<void> _changeIcon(CustomIcon icon) async {
    final currentIcon = icon.currentIcon;
    try {
      await _flutterAppIconChangerPlugin.changeIcon(currentIcon);
      setState(() {
        _currentIcon = icon;
      });
    } on PlatformException catch (e) {
      debugPrint("更改图标失败: '${e.message}'.");
    }
  }
}

更多关于Flutter应用图标更改插件flutter_app_icon_changer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter应用图标更改插件flutter_app_icon_changer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个使用 flutter_app_icon_changer 插件来更改 Flutter 应用图标的示例代码。这个插件允许你在运行时动态更改应用的图标。

首先,确保你的 pubspec.yaml 文件中已经添加了 flutter_app_icon_changer 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_app_icon_changer: ^x.y.z  # 替换为最新版本号

然后运行 flutter pub get 来获取依赖。

接下来,在你的 Flutter 项目中,你可以按照以下步骤使用 flutter_app_icon_changer 插件:

  1. 配置 Android 和 iOS 的备用图标

    你需要在 Android 和 iOS 项目中分别放置你想要使用的备用图标。确保图标的名称和大小符合操作系统的要求。

    • Android:将图标放在 android/app/src/main/res/mipmap-xxxhdpi/mipmap-xxhdpi/mipmap-xhdpi/mipmap-mdpi/ 等目录下。
    • iOS:将图标放在 ios/Runner/Assets.xcassets/AppIcon.appiconset/ 目录下,并且每个尺寸的图标都需要有对应的命名。
  2. 在 Dart 代码中调用插件

    在你的 Flutter 应用的 Dart 代码中,你可以这样使用 flutter_app_icon_changer 插件来更改应用图标:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Change App Icon'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () async {
                  try {
                    // 假设你有一个名为 'new_icon' 的备用图标集
                    bool isChanged = await FlutterAppIconChanger.setAppIcon(
                      android: 'new_icon',
                      ios: 'NewIcon', // 注意:iOS 的图标集名称不需要后缀,例如 '@2x', '@3x'
                    );
                    if (isChanged) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(content: Text('App icon changed successfully!')),
                      );
                    } else {
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(content: Text('Failed to change app icon.')),
                      );
                    }
                  } catch (e) {
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('Error: $e')),
                    );
                  }
                },
                child: Text('Change Icon'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

在这个示例中,当用户点击按钮时,应用会尝试将图标更改为名为 new_icon(Android)和 NewIcon(iOS)的备用图标集。请注意,iOS 的图标集名称在调用时不应包含如 @2x, @3x 的后缀。

注意

  • 动态更改应用图标在某些设备和操作系统版本上可能不受支持。
  • 在发布应用之前,请确保在目标平台上测试图标的更改功能。
  • 应用图标的更改可能不会在设备的主屏幕上立即反映出来,有时需要用户手动重启应用或设备。

希望这个示例能帮助你理解如何使用 flutter_app_icon_changer 插件来更改 Flutter 应用图标。

回到顶部