Загружать шрифты из сети по запросу

Я хочу позволить пользователю выбрать шрифт в моем приложении форм xamarin. У меня есть около 16 шрифтов размером около 10 МБ, размер моего приложения уже слишком велик, это приведет к увеличению размера. Можно ли в любом случае загружать шрифты, когда пользователь хочет изменить шрифт? пожалуйста помоги.

1 ответ

Решение

Я создал образец, который делает именно то, что вам нужно. Вы можете найти исходный код ЗДЕСЬ. Позвольте мне объяснить, что я сделал.

С архитектурной точки зрения нам нужно сделать следующее

  1. Скачать файлы шрифтов из бэкэнда

  2. Кэшируйте эти файлы на устройстве

  3. Убедитесь, что они работают на iOS и Android. На этом этапе нам нужно выполнить некоторые настройки устройства, чтобы шрифты работали. Для iOS нам нужно зарегистрировать шрифты во время выполнения iOS. Для Android нам нужно создать собственные средства визуализации для элементов управления, для которых мы хотим использовать пользовательские шрифты. Читайте дальше для деталей.

  4. Демо ViewModel и View для демонстрации функциональности.

С точки зрения кода, я сделал следующее для реализации вышеупомянутой архитектуры

Создать сервис для загрузки шрифтов

IFontService - сервис для скачивания и установки шрифтов на локальные устройства

public interface IFontService
    {
        //Directory where we'll keep custom fonts
        IFolder FontFolder { get; }
        //Contains mapping between font name and font file
        Dictionary<string, string> Fonts { get; }
        //Will download and install custom fonts and instantiate the Fonts mapping property
        Task LoadAvailableFonts();
    }

РеализоватьIFontService

BaseFontService - реализует большую часть IFontService который не зависит от устройства. У него есть два абстрактных метода, которые должны быть реализованы для конкретного устройства для кэширования и установки шрифтов.

        //We will cache all the fonts in caches folder, which is device specific, 
        //That's why we use abstract property which we'll implement separately for iOS and android
        //and inject into PCL using dependency injection
        protected abstract Task<IFolder> GetCacheFolder();

        //For iOS we need to register custom fonts with iOS runtime. 
        //Check FontService implementation for more details.
        protected abstract Task InstallFonts(IEnumerable<CustomFont> fonts);

Реализуйте специфичные для устройства вещи и используйте внедрение зависимостей

В iOS и Android проектах, которые я создал FontService реализация, которая вытекает из BaseFontService и реализует специфическую для устройства логику - установку шрифтов и кэширование.

Android

Для Android нам нужно только переопределить GetCacheFolder()нам не нужен дополнительный шаг установки для Android, поэтому мы можем оставить InstallFonts() реализация пустая.

Еще один трюк, который нам нужен для Android - это пользовательские средства визуализации для тех элементов управления, для которых мы хотим использовать пользовательский шрифт. В iOS этот шаг не нужен, потому что при регистрации шрифтов вы можете использовать их все вокруг приложения. В моем образце я создал ButtonRenderer а также LabelRenderer, Они просто слушают изменения FontFamily свойство, а затем попробуйте найти этот шрифт, используя IFontService, Я создал FontToolbox класс, который реализует логику загрузки шрифтов в TryGetFont метод. Если вы хотите поддерживать пользовательские шрифты для других элементов управления, вы можете использовать шаблон, аналогичный шаблону для визуализаторов Button/Label, и использовать TryGetFont загрузить фактический шрифт.

IOS

Для iOS это немного сложнее. Нам нужно загрузить файлы шрифтов из каталога кеша и зарегистрировать их с помощью API управления шрифтами ios. Обратитесь сюда для получения более подробной информации

Демо-код

Я создал FontDemoViewModel, который будет вызывать IFontServiceзагрузите доступные шрифты в коллекцию, к которой мы будем привязывать наше представление. Я создал FontDemoPage, который позволит выбрать шрифт из средства выбора (для этого я добавил BindablePickerEx контроль) и обновить шрифты кнопки и метки.

Некоторые заметки

Убедитесь, что имя файла шрифта будет соответствовать имени шрифта PostScript. Это не требуется для Android, потому что Android сможет загружать шрифт с произвольным именем, потому что ему просто нужна ссылка на файл шрифта. Однако для iOS вы должны убедиться, что это правда, так как во время выполнения поиск шрифтов осуществляется по их имени PostScript. Здесь вы можете найти, как получить PostScript имя шрифта.

Другое дело, что в этом примере для простоты я встроил все шрифты в ресурсы сборки. В моем BaseFontService В этом методе я загружаю все шрифты из ресурсов сборки

private async Task<List<CustomFont>> DownloadFonts()

Для вашей реализации вам нужно будет сделать реальные веб-запросы здесь, чтобы загрузить шрифты из вашего бэкэнда.

Другие вопросы по тегам