NovassatSystems.Maui.DynamicIcon 1.1.2

dotnet add package NovassatSystems.Maui.DynamicIcon --version 1.1.2
                    
NuGet\Install-Package NovassatSystems.Maui.DynamicIcon -Version 1.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NovassatSystems.Maui.DynamicIcon" Version="1.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NovassatSystems.Maui.DynamicIcon" Version="1.1.2" />
                    
Directory.Packages.props
<PackageReference Include="NovassatSystems.Maui.DynamicIcon" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NovassatSystems.Maui.DynamicIcon --version 1.1.2
                    
#r "nuget: NovassatSystems.Maui.DynamicIcon, 1.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NovassatSystems.Maui.DynamicIcon@1.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NovassatSystems.Maui.DynamicIcon&version=1.1.2
                    
Install as a Cake Addin
#tool nuget:?package=NovassatSystems.Maui.DynamicIcon&version=1.1.2
                    
Install as a Cake Tool

MADE WITH LOVE .NET MAUI C# Android iOS NuGet

Maui.DynamicIcon

Maui.DynamicIcon é um plugin leve e extensível para .NET MAUI que permite trocar dinamicamente o ícone do app em tempo de execução, utilizando activity-alias no Android e suporte completo no iOS.


📌 Suporte por plataforma

  • ✅ Android 21+
  • ✅ iOS (totalmente suportado)
  • ⚠️ Windows e MacCatalyst não são suportados (ainda sem APIs equivalentes)

🚀 Instalação

1. Adicione o pacote NuGet ao seu projeto MAUI:

NuGet

dotnet add package NovassatSystems.Maui.DynamicIcon

2. Ative o plugin no MauiProgram.cs, informando os aliases disponíveis:

builder.UseDynamicIcon("Icon1Alias", "Icon2Alias", "Icon3Alias");

Configuração do Android

Android

  1. Crie os ícones alternativos
    Coloque os ícones desejados na pasta Resources\Mipmap com nomes diferentes (ex: icon1.png, icon2.png, etc).

  2. Crie activity-alias no AndroidManifest.xml

Dentro da <application> do seu AndroidManifest.xml, adicione um activity-alias para cada ícone alternativo, apontando para sua MainActivity:

<activity-alias
    android:name=".Icon1"
    android:enabled="false"
    android:exported="true"
    android:icon="@mipmap/icon1"
    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=".Icon2"
    android:enabled="false"
    android:exported="true"
    android:icon="@mipmap/icon2"
    android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>
  1. Registre os aliases no MauiProgram.cs
builder.UseDynamicIcon("Icon1", "Icon2");
  1. Importante: o nome usado no código deve ser o mesmo do atributo android:name (sem o ponto inicial se estiver no namespace raiz).

Configuração do iOS

iOS

  1. Crie múltiplos ícones no formato .appiconset

Crie conjuntos de ícones separados com os nomes desejados, por exemplo:

Assets.xcassets/
├── AppIcon.appiconset (ícone padrão)
├── Icon1.appiconset
├── Icon2.appiconset
  1. Configure o Info.plist

No seu Info.plist, adicione a chave CFBundleIcons com os ícones alternativos:

<key>CFBundleIcons</key>
<dict>
  <key>CFBundleAlternateIcons</key>
  <dict>
    <key>Icon1</key>
    <dict>
      <key>CFBundleIconFiles</key>
      <array>
        <string>Icon1</string>
      </array>
      <key>UIPrerenderedIcon</key>
      <false/>
    </dict>
    <key>Icon2</key>
    <dict>
      <key>CFBundleIconFiles</key>
      <array>
        <string>Icon2</string>
      </array>
      <key>UIPrerenderedIcon</key>
      <false/>
    </dict>
  </dict>
</dict>
  1. Registre os aliases no MauiProgram.cs
builder.UseDynamicIcon("Icon1", "Icon2");
  1. Utilize normalmente com o plugin
await DynamicIcon.Current.SetIconAsync("Icon1");

✨ Exemplos de uso

🔧 1. Usando injeção de dependência com DynamicIconManager

public class MainViewModel(DynamicIconManager iconManager)
{
    readonly DynamicIconManager _iconManager = iconManager;
    int _counter = 0;

    public async void ToggleIconWithDynamicIconManager()
    {
        var alias = _counter++ % 2 == 0 ? "Icon1" : "Icon2";
        await _iconManager.SetAliasOnceAsync(alias);
    }
}

Útil quando você injeta o DynamicIconManager via DI no seu ViewModel, mantendo o controle do fluxo manualmente.


♻️ 2. Usando Strategy Pattern com DynamicIconManager

public class MainViewModel(DynamicIconManager iconManager)
{
    readonly DynamicIconManager _iconManager = iconManager;

    public async void ToggleIconWithDynamicIconManagerAndStrategy()
    {
        _iconManager.SetStrategy(new SingleUseStrategy(true));
        await _iconManager.ApplyStrategyAsync();
    }
}

public class SingleUseStrategy(bool mustBeChange) : IDynamicIconStrategy
{
    private readonly string _alias = mustBeChange ? "Icon1" : "Icon2";
    public string? GetNextIconAlias() => _alias;
}

Ideal para cenários com regras complexas de alternância ou personalização futura da lógica de troca de ícone.


⚡ 3. Acesso direto com DynamicIcon.Current (estático)

public class MainViewModel
{
    int _counter = 0;

    public async Task ToggleIconWithDynamicIconCurrent()
    {
        var alias = _counter++ % 2 == 0 ? "Icon1" : "Icon2";
        await DynamicIcon.Current.SetIconAsync(alias);
    }
}

Alternativa rápida para uso direto sem injeção de dependência — útil em projetos simples ou em code-behind.


🛠️ Considerações no modo Debug (Android)

Ao ativar um alias, o plugin desativa a MainActivity, o que pode causar falha no deploy pelo Visual Studio com o erro:

Error: Activity class ...MainActivity does not exist.

Possíveis soluções:

  • Chame _iconManager.ResetToDefault(); antes de iniciar o app
  • Ou reative manualmente via ADB:
adb shell pm enable seu.pacote/.MainActivity

📂 Projeto de exemplo

Confira o projeto Maui.DynamicIcon.Sample no repositório para testar e experimentar as funcionalidades em tempo real.


⚙️ Demonstração

Alternância de ícones em tempo real – trabalhando em um gif para ilustrar em breve.

(Placeholder para link ou GIF)


🧰 Tecnologias utilizadas


🤝 Contribuindo

Contribuições são super bem-vindas! Abra issues, envie pull requests ou dê sugestões nas Discussions.


📄 Licença

Este projeto é licenciado sob MIT.


📞 Contato

Se tiver dúvidas ou sugestões:


GitHub repo size GitHub language count GitHub forks GitHub issues GitHub pull requests

Product Compatible and additional computed target framework versions.
.NET net9.0-android35.0 is compatible.  net9.0-ios18.0 is compatible.  net10.0-android was computed.  net10.0-ios was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0-android35.0

    • No dependencies.
  • net9.0-ios18.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.2 428 6/11/2025