Я хочу, чтобы пользователь мог выбрать шрифт в приложении формы xamarin. У меня около 16 шрифтов размером около 10 МБ, и мой размер приложения слишком велик, что приведет к большему размеру. В любом случае я могу загружать шрифты, когда пользователь хочет изменить шрифт? пожалуйста помоги.Загрузка шрифтов из сети по запросу
ответ
Я создал образец, который делает именно то, что вам нужно. Вы можете найти исходный код HERE. Позвольте мне объяснить, что я сделал.
С архитектурной точки зрения, мы должны сделать следующий
Скачать файлы шрифты из бэкэнда
Cache этих файлы на устройстве
Убедитесь в том, что они работают на прошивке и Android. На этом этапе нам нужно настроить некоторые настройки устройства, чтобы заставить шрифты работать. Для iOS нам нужно зарегистрировать шрифты с помощью среды выполнения iOS. Для Android нам нужно создать собственные средства визуализации для элементов управления, для которых мы хотим использовать пользовательские шрифты. Подробнее см. Далее.
Демо-модель 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
. Если вы хотите поддерживать пользовательские шрифты для других элементов управления, вы можете использовать аналогичный шаблон, как в средствах создания кнопок/меток, и использовать TryGetFont
для загрузки фактического шрифта.
IOS
Для прошивки это немного сложнее. Нам нужно загрузить файлы шрифтов из каталога кеша и зарегистрировать их с помощью API управления шрифтами ios. См here для более подробной информации
Демо-код
Я создал FontDemoViewModel, который будет вызывать IFontService
, загрузите доступные шрифты в коллекции, к которой мы будем связываться с нашей точки зрения. Я создал FontDemoPage, который позволит выбрать шрифт из сборщика (для него я добавил BindablePickerEx
control) и обновить шрифты кнопки и метки.
Некоторые примечания
Убедитесь, что имя файла шрифта будет совпадать с именем PostScript шрифта. Это не требуется для Android, потому что Android сможет загружать шрифт с произвольным именем, потому что ему просто нужна ссылка на файл шрифта. Однако для iOS вам нужно убедиться, что это правда, поскольку во время выполнения поиск шрифтов происходит по имени PostScript. Here вы можете найти, как получить PostScript-имя шрифта.
Другое дело, что в этом примере для простоты я включил все шрифты в ресурсы сборки. В моих BaseFontService
я загрузить все шрифты из сборочных ресурсов в этом методе
private async Task<List<CustomFont>> DownloadFonts()
Для вашей реализации вы должны сделать фактический веб-запросы здесь, чтобы загрузить шрифты из вашего внутреннего интерфейса.
Отлично. Хорошая работа. спасибо – Krishna
Я считаю, что пользовательские шрифты должны быть включены в комплект приложений – Jason
@Jason Я знаю, но нахожу дополнительные возможности. Я знаю, что мы можем создать каталог активов и загрузить их отдельно от пакета. Но не уверен, можно ли делать шрифты так. Также нужно найти способ для других платформ. – Krishna
Я стою исправлен - возможно, это возможно в iOS. См. Http://stackoverflow.com/questions/19776285/ios-apps-can-download-the-following-fonts-if-necessary – Jason