A flutter plugin that makes changing your app's icon within the app easy
Icon Switcher
Icon Switcher is a plugin that makes changing your app’s icon within the app easy. See a short demo below:
Demo
How to use
iOS
Click to expandPrerequisites
- Important: This package doesn’t handle the initial App Icon. You must provide/set this yourself.
- iOS 10.3 and above.
- Images in @1x, @2x, and @3x sizes like standard iOS images. A tool for this can be found here (It can also be used for Android).
Preparation
- Open
Runner.xcworkspace
from your project in XCode. - Create a folder named
App Icons
in the Runner folder. - In this folder, place your app icons as follows:
Then, modify the info.plist
as shown:
...
<plist version="1.0">
<dict>
<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>
...
Replace NAME and NAME2 with the names of your app icon files.
After that, you’re ready to go!
Android
Click to expandPrerequisites
- IMPORTANT: Android is not providing a solution for changing the App Icon by default as IOS does, so this way may not be the cleanest and best, but it works.
- You need to know your
applicationId
by default it is:com.example.example
- Images in mipmap format just like the default android icon. Find a tool for this: here (Can also be used for the IOS ones)
Preperation
- Put your images in the destination folders:
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-xxhdpi
andyour_project/android/app/src/main/res/mipmap-xxxhdpi
Go to your_project/android/app/src/main/AndroidManifest.xml
and here you
need to add for each icon an entry like this:
...
</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>
...
The NameOfTheMipMapImage
must just be the name of the image you put in the mipmap folders (Please feel free to checkout my example).
The NameOfYourActivity
is really important! Because now we need to create a Activity Class in our Android Project, for this I just edited the MainActivity.kt
file located under: your_project/android/app/src/main/kotlin/com/example/example/MainActivity.kt
In this file you need to create new activity classes with the name you specified in NameOfYourActivity
.
Example:
My 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>
As you can see I need to create a class called First
just like this:
package com.example.example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
//NEW:
class First: FlutterActivity() {
}
Flutter/Dart part
Sadly we also have one different thing to setup here for Android:
IconSwitcher.setDefaultComponent("com.example.example.MainActivity");
This we need to call when our App starts, please also feel free to look into my example App how I did this. Important here, the applicationId and the MainActivity name must be correct, please double check this in case of errors.
Using the Icon_Switcher in a Flutter App
To now switch the icon after you are done with the IOS and/or Android Setup above you can just call this method:
await IconSwitcher.changeIcon('first', 'com.example.example.First');
The first argument here is the IconName, this part is necessary for IOS mostly, the second argument is the Activity with the ApplicationId of Android.
Note
Please be aware that the Android solution is as stated before not the best solution but however it works, for me it takes a bit until Android updates the App on the Homescreen so pressing on an Icon and getting the message Unknown App or something like this can happen! It takes a few moments and than the App is again back with the new Icon and can be started without any issues.