Flutter图标切换插件mobile_icon_switcher的使用

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

Flutter图标切换插件mobile_icon_switcher的使用

Mobile Icon Switcher 是一个使应用程序能够在应用内部轻松更改图标的插件。以下是简短的演示:

演示

演示

如何使用

iOS

前提条件

  • 重要:此包不处理初始应用程序图标。必须自行提供或设置。
  • iOS 10.3及以上版本。
  • 图片大小为@1x, @2x, 和 @3x,就像标准的iOS图像一样。可以使用以下工具进行处理:这里(也可用于Android)。

准备工作

  1. 在XCode中打开项目中的Runner.xcworkspace
  2. 在Runner文件夹中创建一个名为App Icons的文件夹。
  3. 将你的应用图标放入该文件夹,分别命名为Name[@1x](/user/1x).png, Name[@2x](/user/2x).png, 和 Name[@3x](/user/3x).png

然后,修改info.plist文件,如示例所示:

...
<key>CFBundleIcons</key>
    <dict>
        <key>CFBundleAlternateIcons</key>
        <dict>
            <key>NAME</key>
            <dict>
                <key>UIPrerenderedIcon</key>
                <string>NO</string>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>NAME</string>
                </array>
            </dict>
            <key>NAME2</key>
            <dict>
                <key>UIPrerenderedIcon</key>
                <string>NO</string>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>NAME2</string>
                </array>
            </dict>
        </dict>
    </dict>
...

NAMENAME2替换为你实际的应用图标文件名。

完成后,你就可以开始使用了!

Android

前提条件

  • 重要:Android 默认不提供通过代码更改应用图标的解决方案,因此这种方法可能不是最干净和最好的,但它是有效的。
  • 你需要知道你的applicationId,默认为:com.example.example
  • 图片格式为mipmap,就像默认的Android图标一样。可以使用以下工具进行处理:这里(也可以用于iOS)。

准备工作

  1. 将你的图片放入目标文件夹:your_project/android/app/src/main/res/mipmap-anydpi-v26, your_project/android/app/src/main/res/mipmap-hdpi, your_project/android/app/src/main/res/mipmap-mdpi, your_project/android/app/src/main/res/mipmap-xhdpi, your_project/android/app/src/main/res/mipmap-xxhdpiyour_project/android/app/src/main/res/mipmap-xxxhdpi

  2. 打开your_project/android/app/src/main/AndroidManifest.xml文件,并为每个图标添加一个条目,如下所示:

...
        </activity>
        <!--START HERE: -->
        <activity-alias
            android:name=".NameOfYourActivity"
            android:targetActivity=".MainActivity"
            android:icon="@mipmap/NameOfTheMipMapImage"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>
        ...

NameOfTheMipMapImage必须是你放置在mipmap文件夹中的图片名称(请参考我的示例)。

NameOfYourActivity非常重要!因为现在我们需要在Android项目中创建一个活动类。我编辑了your_project/android/app/src/main/kotlin/com/example/example/MainActivity.kt文件,在这个文件中,你需要创建与你在NameOfYourActivity中指定的名称相同的新活动类。

示例

我的AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:label="example"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <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>
        <!--IMPORTANT START HERE: -->
        <activity-alias
            android:name=".First"
            android:targetActivity=".MainActivity"
            android:icon="@mipmap/first"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

可以看到,我需要创建一个名为First的类,如下所示:

package com.example.example

import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {
}

//NEW:
class First: FlutterActivity() {
}

Flutter/Dart部分

不幸的是,对于Android我们还需要设置一些不同的东西:

MobileIconSwitcher.setDefaultComponent("com.example.example.MainActivity");

当我们启动应用时需要调用这个方法,请也查看我的示例应用是如何实现的。重要的是,applicationIdMainActivity的名称必须正确,请在出错的情况下仔细检查。

在Flutter应用中使用mobile_icon_switcher

切换应用图标

完成上述iOS和/或Android设置后,你可以通过调用以下方法来切换应用图标:

await MobileIconSwitcher.changeIcon('first', 'com.example.example.First');

这里的第一个参数是图标名称,这对于iOS来说是必要的,第二个参数是带有Android应用ID的活动。

重置应用图标到默认值

完成上述iOS和/或Android设置后,你可以通过调用以下方法将应用图标重置为默认值:

await MobileIconSwitcher.resetIcon();

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

1 回复

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


当然,下面是一个关于如何在Flutter中使用mobile_icon_switcher插件来实现图标切换的代码示例。mobile_icon_switcher插件允许你轻松地在应用中切换图标,例如,在用户切换主题时改变应用图标。

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

dependencies:
  flutter:
    sdk: flutter
  mobile_icon_switcher: ^最新版本号

然后,运行flutter pub get来安装依赖。

接下来是一个完整的示例,展示了如何使用mobile_icon_switcher插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: IconSwitcherDemo(),
    );
  }
}

class IconSwitcherDemo extends StatefulWidget {
  @override
  _IconSwitcherDemoState createState() => _IconSwitcherDemoState();
}

class _IconSwitcherDemoState extends State<IconSwitcherDemo> {
  bool isDarkMode = false;

  void toggleTheme() {
    setState(() {
      isDarkMode = !isDarkMode;
      changeAppIcon(isDarkMode);
    });
  }

  void changeAppIcon(bool isDark) async {
    try {
      if (await MobileIconSwitcher.isSupported()) {
        if (isDark) {
          await MobileIconSwitcher.setAppIcon(
            name: 'ic_launcher_dark', // 在AndroidManifest.xml中定义的图标名称
            packageName: 'com.example.yourapp', // 你的应用包名
          );
        } else {
          await MobileIconSwitcher.setAppIcon(
            name: 'ic_launcher_light', // 在AndroidManifest.xml中定义的图标名称
            packageName: 'com.example.yourapp', // 你的应用包名
          );
        }
      } else {
        print('更改图标功能不支持当前设备或系统');
      }
    } catch (e) {
      print('更改图标时发生错误: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Icon Switcher Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '当前模式: ${isDarkMode ? '深色' : '浅色'}',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: toggleTheme,
              child: Text('切换主题/图标'),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项:

  1. AndroidManifest.xml配置: 你需要在AndroidManifest.xml中为你的图标配置别名。例如:

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher_light"
        android:roundIcon="@mipmap/ic_launcher_round_light"
        android:theme="@style/LaunchTheme"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data
            android:name="android.app.shortcuts"
            android:resource="@xml/shortcuts" />
        <!-- 配置图标别名 -->
        <activity-alias
            android:name=".DarkIconActivity"
            android:enabled="false"
            android:icon="@mipmap/ic_launcher_dark"
            android:label="@string/app_name"
            android:targetActivity=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>
        <activity-alias
            android:name=".LightIconActivity"
            android:enabled="true"
            android:icon="@mipmap/ic_launcher_light"
            android:label="@string/app_name"
            android:targetActivity=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>
    </activity>
    
  2. 权限问题: 某些设备和Android版本可能不支持动态更改图标,或者需要特定的权限。请确保在AndroidManifest.xml中声明必要的权限,并处理可能的异常情况。

  3. iOS支持mobile_icon_switcher插件目前主要支持Android平台。对于iOS,动态更改应用图标的功能通常不被支持,因此你可能需要实现其他UI/UX策略来模拟类似的效果。

希望这个示例能帮助你理解如何在Flutter中使用mobile_icon_switcher插件来实现图标切换。

回到顶部