Xamarin.Forms-在应用程序中方便使用图标字体


问题陈述


您可以使用各种格式的图像(例如png,svg或ttf字体)在Xamarin.Forms应用程序中显示图标。 大多数情况下,带有图标的字体便于添加标准图标,例如google material图标。 带图标的字体的大小约为200K,可用性通常比节省应用程序大小更重要。 图标在任何屏幕分辨率下都将看起来不错,并且为黑白。

有现成的nuget软件包,可以使用图标。 我使用图标化很长时间了( nuget-www.nuget.org/packages/Xam.Plugin.Iconize ; git-github.com/jsmarcus/Iconize )。 它允许您连接十多种字体,添加新控件,例如IconButton,IconImage,IconLabel等。 但是这里有针对现成库的通常争论:额外的功能,额外的文件大小,对行为不完全满意,错误等。 因此,在某个时候,我决定放弃已完成的库,并用一对带有类和字体的简单自行车替换它。

ttf字体中的图标在xaml中的使用方式如下(iOS):

<Label Text="&#xe5d2;" FontFamily="MaterialIcons-Regular"/> 

在C#中:

 var label = new Label { Text ="\ue5d2", FontFamily = "MaterialIcons-Regular" }; 

我将列出出现的问题。

1.以不同的格式在XAML和C#中编写图标代码(“&#xe5d2;” /“ \ ue5d2”)

2.图标代码与图标本身不相关,我想使用诸如“ arrow_back”之类的图标

3.如果应用程序将在android和iOS上运行,则需要以不同的方式写字体名称-android中的“ MaterialIcons-Regular.ttf#MaterialIcons-Regular”和iOS中的“ MaterialIcons-Regular”

此处描述的解决方案需要Label控件上的TextChanged事件。 将此问题添加到列表中:

4. Label控件没有TextChanged事件。 我们需要它来跟踪标签文本的更改并在xaml中使用绑定

解决方案


例如,采用字体google material图标。 首先,将其添加到android和iOS项目中。
在这里下载字体
图标在这里搜索

下载字体文件-MaterialIcons-Regular.ttf。

Android:
将MaterialIcons-Regular.ttf添加到Assets文件夹,然后为其选择“ Build action” AndroidAsset。

iOS:
将MaterialIcons-Regular.ttf添加到Resources \ Fonts文件夹,并为其选择“ Build action” BundleResource,然后将字体写入info.plist中:

 <key>UIAppFonts</key> <array> <string>Fonts/MaterialIcons-Regular.ttf</string> </array> 

现在假设我们想要在应用程序中使用向左箭头图标。 我们转到带有图标搜索引擎的页面: https : //material.io/resources/icons/ ,在左上角输入“箭头”,然后在结果中选择左箭头。 现在,单击“选定的图标”面板以查看图标代码...,但它不存在:

 Usage: <!--For modern browsers--> <i class="material-icons"> arrow_back </i> <!-- For IE9 or below. --> <i class="material-icons"> arrow_back </i> 

是的,每次将名称转换成代码然后找出应用程序代码中的图标并不是很方便。 像这样使用图标的友好名称“ arrow_back”会更方便:

 <Label Text="arrow_back"> 

对于解决方案,我们将在“对Xamarin.Forms事件的反应”的俄语翻译中使用所谓的行为( https://docs.microsoft.com/ru-ru/xamarin/xamarin-forms/app-fundamentals/behaviors/

为此,请创建GoogleMaterialFontBehavior类:

 public class GoogleMaterialFontBehavior: BehaviorBase<CustomLabel> { } 

我们的行为将响应不断变化的标签文本,因此Label也必须最终确定:

 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()); } } } 

在GoogleMaterialFontBehavior类中,您需要:

  • 重写OnAttachedTo / OnDetachingFrom方法
  • 添加文本更改处理程序:HandleTextChanged
  • 添加字体名称fontFamily
  • 并添加一个字符代码目录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(); } } // private static readonly string fontFamily = Device.RuntimePlatform == Device.Android ? "MaterialIcons-Regular.ttf#MaterialIcons-Regular" : "MaterialIcons-Regular"; private static readonly Dictionary<string, char> iconCodeDict = new Dictionary<string, char> { {"3d_rotation", '\ue84d'}, {"ac_unit", '\ueb3b'}, {"access_alarm", '\ue190'}, … } } } 

现在,关于iconCodeDict引用本身。 它将包含字体字符的名称代码对。 对于google material图标,此数据位于单独文件中的git存储库中: github.com/google/material-design-icons/blob/master/iconfont/codepoints

使用范例


XAML:

在页面顶部添加2个名称空间:

 xmlns:uc="clr-namespace:MyApp.UserControls" xmlns:b="clr-namespace:MyApp.Behaviors" 

并显示图标:

 <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"; 

选配


我也非常喜欢字体Jam图标。 让我们为其创建一个JamFontBehavior类,类似于GoogleMaterialFontBehavior。 其他将是:fontFamily和iconCodeDict。

在此处下载字体: https : //github.com/michaelampr/jam/blob/master/fonts/jam-icons.ttf
要在此处搜索的图标: https//jam-icons.com/

非常方便的搜索引擎。 找到图标,单击它,然后在剪贴板上命名。 只需将其插入代码即可。

除了获取图标代码外,该算法与Google图标相同。

代码必须取自位于同一位置的svg文件。

使用诸如sublime之类的文本编辑器可以轻松地提取数据。 选择“ data-tags”行,按Alt + F3,打开多光标。 下一班+上门,Ctrl + C,Ctrl + A,Ctrl +V。 依此类推。 在Excel的帮助下,这是可能的。

例如,在svg文件中,左箭头如下所示:

 <glyph unicode="&#xe92b;" 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" /> 

清除文本后,我们获得字形名称和unicode字段的内容:

 {"arrow-left", '\ue92b'} 

并将iconCodeDict添加到字典中

Source: https://habr.com/ru/post/zh-CN467423/


All Articles