Énoncé du problème
Vous pouvez utiliser des images dans différents formats, par exemple des polices png, svg ou ttf, pour afficher des icônes dans l'application Xamarin.Forms. Le plus souvent, une police avec des icônes est pratique pour ajouter des icônes standard, par exemple des icônes de matériel Google. La police avec des icônes a une taille d'environ 200 Ko et la convivialité est généralement plus importante que d'économiser sur la taille de l'application. Les icônes seront bonnes à n'importe quelle résolution d'écran et seront en noir et blanc.
Il existe des packages de nuget prêts à l'emploi pour l'utilisation des icônes. J'ai utilisé iconize pendant longtemps (nuget -
www.nuget.org/packages/Xam.Plugin.Iconize ; git -
github.com/jsmarcus/Iconize ). Il vous permet de connecter plus de dix polices, ajoute de nouveaux contrôles, tels que IconButton, IconImage, IconLabel, etc. Mais ici, il y a les arguments habituels contre les bibliothèques prêtes à l'emploi: fonctionnalités supplémentaires, taille de fichier supplémentaire, pas complètement satisfait du comportement, bogues, etc. Par conséquent, à un moment donné, j'ai décidé d'abandonner la bibliothèque terminée et de la remplacer par un simple vélo d'une paire de classes + police.
L'icône de la police ttf est utilisée dans xaml comme suit (iOS):
<Label Text="" FontFamily="MaterialIcons-Regular"/>
En C #:
var label = new Label { Text ="\ue5d2", FontFamily = "MaterialIcons-Regular" };
Je vais énumérer les problèmes qui se posent.
1. format différent pour écrire le code d'icône en XAML et C # ("& # xe5d2;" / "\ ue5d2")
2. le code d'icône n'est pas associé à l'icône elle-même, je voudrais utiliser quelque chose comme "arrow_back", comme dans iconize
3. Si l'application s'exécute sur Android et iOS, vous devez écrire le nom de la police différemment - "MaterialIcons-Regular.ttf # MaterialIcons-Regular" dans Android et "MaterialIcons-Regular" dans iOS
La solution décrite ici nécessite l'événement TextChanged sur le contrôle Label. Ajoutez ce problème à la liste:
4. le contrôle Label n'a pas d'événement TextChanged. Nous en avons besoin pour suivre les modifications du texte des étiquettes et utiliser la liaison dans xaml
Solution
Par exemple, prenez les icônes de matériau de la police google. Tout d'abord, ajoutez-le aux projets Android et iOS.
Téléchargez la police iciRecherche d'icônes iciTéléchargez le fichier de police - MaterialIcons-Regular.ttf.
Android:
Ajoutez MaterialIcons-Regular.ttf dans le dossier Assets et sélectionnez AndroidAsset «Build action» pour lui.
iOS:
Ajoutez MaterialIcons-Regular.ttf au dossier Resources \ Fonts et sélectionnez le BundleResource «Build action», puis écrivez la police dans info.plist:
<key>UIAppFonts</key> <array> <string>Fonts/MaterialIcons-Regular.ttf</string> </array>
Supposons maintenant que nous voulons une icône de flèche gauche dans notre application. Nous allons à la page avec le moteur de recherche d'icônes:
https://material.io/resources/icons/ , entrez "flèche" dans le coin supérieur gauche, sélectionnez la flèche gauche dans les résultats. Maintenant, cliquez sur le panneau "Icône sélectionnée" pour voir le code de l'icône ... mais il n'y est pas:
Usage: <i class="material-icons"> arrow_back </i> <i class="material-icons"> arrow_back </i>
Oui, et ce n'est pas très pratique de traduire les noms en codes à chaque fois, puis de comprendre ce qu'est l'icône dans le code de l'application. Il serait plus pratique d'utiliser le nom convivial de l'icône - "arrow_back" comme ceci:
<Label Text="arrow_back">
Pour la solution, nous utiliserons le soi-disant comportement dans la traduction russe de «Réactions aux événements Xamarin.Forms» (
https://docs.microsoft.com/ru-ru/xamarin/xamarin-forms/app-fundamentals/behaviors/ )
Pour ce faire, créez la classe GoogleMaterialFontBehavior:
public class GoogleMaterialFontBehavior: BehaviorBase<CustomLabel> { }
Notre comportement réagira à la modification du texte de l'étiquette, de sorte que l'étiquette devra également être finalisée:
using System; using Xamarin.Forms; namespace MyApp.UserControls { public class CustomLabel : Label { public event EventHandler<EventArgs> TextChanged; public static readonly new BindableProperty TextProperty = BindableProperty.Create( propertyName: nameof(Text), returnType: typeof(string), declaringType: typeof(CustomLabel), defaultValue: "", defaultBindingMode: BindingMode.OneWay, propertyChanged: TextChangedHandler); public new string Text { get => (string)GetValue(TextProperty); set { base.Text = value; SetValue(TextProperty, value); } } private static void TextChangedHandler(BindableObject bindable, object oldValue, object newValue) { var control = bindable as CustomLabel; control.TextChanged?.Invoke(control, new EventArgs()); } } }
Dans la classe GoogleMaterialFontBehavior, vous avez besoin de:
- remplacer les méthodes OnAttachedTo / OnDetachingFrom
- ajouter un gestionnaire de changement de texte: HandleTextChanged
- ajouter le nom de police fontFamily
- et également ajouter un répertoire de codes de caractères iconCodeDict
namespace MyApp.Behaviors { public class GoogleMaterialFontBehavior: BehaviorBase<CustomLabel> { protected override void OnAttachedTo(CustomLabel bindable) { HandleTextChanged(bindable, null); bindable.TextChanged += HandleTextChanged; base.OnAttachedTo(bindable); } protected override void OnDetachingFrom(CustomLabel bindable) { bindable.TextChanged -= HandleTextChanged; base.OnDetachingFrom(bindable); } private void HandleTextChanged(object sender, EventArgs e) { var label = (CustomLabel)sender; if (label?.Text?.Length >= 2 && iconCodeDict.TryGetValue(label.Text, out var icon)) { label.FontFamily = fontFamily; label.Text = icon.ToString(); } }
Et maintenant sur la référence iconCodeDict elle-même. Il contiendra des paires nom-code pour les caractères de police. Dans le cas des icônes de matériaux Google, ces données se trouvent dans un référentiel git dans un fichier séparé:
github.com/google/material-design-icons/blob/master/iconfont/codepointsExemple d'utilisation
XAML:
en haut de la page ajoutez 2 espaces de noms:
xmlns:uc="clr-namespace:MyApp.UserControls" xmlns:b="clr-namespace:MyApp.Behaviors"
et afficher l'icône:
<uc:CustomLabel Text="arrow_back" FontSize="30"> <Label.Behaviors> <b:GoogleMaterialFontBehavior /> </Label.Behaviors> </uc:CustomLabel>
C #:
var label = new CustomLabel(); label.Behaviors.Add (new GoogleMaterialFontBehavior()); label.Text = "arrow_back";
En option
J'ai aussi beaucoup aimé les icônes de polices Jam. Créons une classe JamFontBehavior, similaire à GoogleMaterialFontBehavior. Les autres seront: fontFamily et iconCodeDict.
Téléchargez la police ici:
https://github.com/michaelampr/jam/blob/master/fonts/jam-icons.ttfIcônes à rechercher ici:
https://jam-icons.com/Moteur de recherche très pratique. Trouvez l'icône, cliquez dessus et le nom dans le presse-papiers. Il reste à simplement l'insérer dans le code.
L'algorithme est le même que pour les icônes Google, sauf pour obtenir des codes d'icône.
Les codes doivent être extraits du fichier svg situé
au même endroit .
Les données peuvent être facilement extraites à l'aide d'un éditeur de texte tel que sublime. Sélectionnez la ligne "data-tags", appuyez sur Alt + F3, le multi-curseur est activé. Maj suivant + accueil, ctrl + c, ctrl + a, ctrl + v. Et ainsi de suite. C'est possible avec l'aide d'Excel, à qui est plus familier.
Par exemple, la flèche gauche ressemble à ceci dans le fichier svg:
<glyph unicode="" glyph-name="arrow-left" data-tags="arrow-left" d="M358.997 398.635l168.533-168.533c7.15-7.611 11.543-17.885 11.543-29.185 0-23.564-19.103-42.667-42.667-42.667-11.311 0-21.594 4.401-29.229 11.585l0.022-0.020-241.365 241.323c-7.749 7.706-12.545 18.376-12.545 30.165s4.796 22.459 12.544 30.163l241.367 241.367c7.769 8.036 18.647 13.026 30.69 13.026 23.564 0 42.667-19.103 42.667-42.667 0-12.043-4.989-22.92-13.014-30.678l-168.545-168.545h409.003c23.564 0 42.667-19.103 42.667-42.667s-19.103-42.667-42.667-42.667v0h-409.003z" />
Après avoir effacé le texte, nous obtenons le contenu des champs glyph-name et unicode:
{"arrow-left", '\ue92b'}
et ajoutez iconCodeDict au dictionnaire