Flutter SVG Icon ColorFilter vs Opacity
Problème
Les icônes SVG rendus avec flutter_svg apparaissent invisibles ou ont une visibilité incorrecte
lorsque vous utilisez le widget Opacity pour indiquer les états sélectionné/non sélectionné. Cela se produit généralement
dans les barres de navigation inférieure, les barres d'onglets, ou toute interface utilisateur avec des changements d'état d'icône.
Contexte / Conditions de déclenchement
- Utilisation du package
flutter_svgavecSvgPicture.asset() - Les fichiers SVG ont des couleurs de remplissage explicites (ex.
fill="white") - Les icônes enveloppées dans le widget
Opacitypour les états sélectionné/non sélectionné - Les icônes apparaissent invisibles ou à peine visibles malgré un contenu SVG correct
- La couleur de fond devrait fournir un contraste suffisant (ex. blanc sur vert foncé)
Solution
Remplacez le widget Opacity par ColorFilter sur le SvgPicture :
Avant (problématique) :
Widget _buildTabButton(String iconPath, bool isSelected) {
return Opacity(
opacity: isSelected ? 1.0 : 0.5,
child: SvgPicture.asset(iconPath, width: 32, height: 32),
);
}
Après (correct) :
Widget _buildTabButton(String iconPath, bool isSelected) {
final iconColor = isSelected ? Colors.white : Colors.grey;
return SvgPicture.asset(
iconPath,
width: 32,
height: 32,
colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn),
);
}
Points clés
-
ColorFilter.mode avec BlendMode.srcIn remplace la couleur de remplissage du SVG par la couleur spécifiée partout où le SVG a des pixels opaques
-
Ne vous fiez pas à Opacity pour les changements de couleur - Opacity affecte la transparence mais ne change pas la couleur réelle rendue, ce qui peut causer des problèmes de visibilité
-
L'attribut fill du SVG est remplacé - Même si votre SVG a
fill="white", le ColorFilter le remplacera par votre couleur spécifiée
Vérification
Après application de la correction :
- Les icônes sélectionnées doivent s'afficher dans la couleur sélectionnée (ex. blanc)
- Les icônes non sélectionnées doivent s'afficher dans la couleur non sélectionnée (ex. gris)
- Les deux états doivent être clairement visibles sur le fond
Exemple
Barre de navigation inférieure avec coloration appropriée des icônes :
Widget _buildNavIcon(String assetPath, int tabIndex, int currentIndex) {
final isSelected = tabIndex == currentIndex;
final iconColor = isSelected ? Colors.white : const Color(0xFF8A9A94);
return GestureDetector(
onTap: () => _onTabTap(tabIndex),
child: Container(
width: 48,
height: 48,
padding: const EdgeInsets.all(8),
child: SvgPicture.asset(
assetPath,
width: 32,
height: 32,
colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn),
),
),
);
}
Remarques
- Cela s'applique spécifiquement au package
flutter_svg; les autres solutions de rendu SVG peuvent se comporter différemment - Si vous avez besoin à la fois du changement de couleur ET de l'opacité, appliquez d'abord le ColorFilter, puis enveloppez dans Opacity si vraiment nécessaire
- Pour les icônes qui doivent conserver leur apparence multicolore d'origine, n'utilisez pas ColorFilter - mais dans ce cas Opacity seul peut fonctionner correctement
- BlendMode.srcIn signifie spécifiquement « afficher la couleur source où la destination (SVG) est opaque »