Каждый раз, когда мы загружаем изображения из Интернета, есть вероятность, что загрузка не удалась. Для лучшего взаимодействия с пользователем важно иметь готовый механизм заполнителя. В этом посте я покажу вам, как я расширил свой форк Xamarin.Forms.Nuke для достижения этой цели на iOS.
Что такое Xamarin.Forms.Nuke?
Xamarin.Forms.Nuke - это реализация Xamarin.Forms Nuke, одной из самых продвинутых библиотек изображений для iOS на сегодняшний день. Реализация Xamarin.Forms в значительной степени ориентирована только на кеширование, в то время как исходная библиотека имеет множество дополнительных функций. Я узнал об этой библиотеке, когда начал искать альтернативу кэшированию изображений через Akavache, который я использовал раньше (я никогда не писал об этой части, потому что она не была готова к этому, tbh).
Зачем нужно расширять библиотеку?
В настоящее время библиотека делает только одно (очень хорошо) - обрабатывает кеширование веб-изображений. Он использует настройки по умолчанию собственной библиотеки Nuke. Реализация Xamarin.Forms
перезаписывает ImageSourceHandler
для UriImageSource
и FileImageSource
(необязательно), но случай загрузки заполнителя не предусмотрен в исходной версии. Поскольку у меня есть несколько сценариев, в которых может пригодиться заполнитель, я решил расширить библиотеку - и с этого момента поддерживать ее собственный форк. (Может быть, тоже будет запрос на перенос к первоисточнику).
Покажи мне наконец код!
Для нашего расширения мы модифицируем класс FormsHandler
, а также класс ImageSourceHandler
. Давайте сначала посмотрим на класс FormsHandler
. Мы добавляем новое свойство для заполнителя:
public static ImageSource PlaceholderImageSource { get; private set; }
Я выбрал класс FormsHandler
, потому что установка заполнителя - это глобальная вещь (в моих сценариях ваш пробег может отличаться). Это уже все, что есть в классе FormsHandler
, поэтому давайте взглянем на класс ImageSourceHandler
.
Поскольку мы используем значение по умолчанию Xamarin.Forms
ImageSourceHandler
для изображения ресурса (это StreamImageSource
) и FontImageSource
, нам нужно сначала добавить для них статические поля:
private static readonly StreamImagesourceHandler DefaultStreamImageSourceHandler = new StreamImagesourceHandler(); private static readonly FontImageSourceHandler DefaultFontImageSourcehandler = new FontImageSourceHandler();
Теперь давайте реализуем загрузку заполнителя отдельным методом:
private static Task<UIImage> LoadPlaceholderAsync() { switch (FormsHandler.PlaceholderImageSource) { case StreamImageSource streamImageSource: FormsHandler.Warn($"loading placeholder from resource"); return DefaultStreamImageSourceHandler.LoadImageAsync(streamImageSource); case FontImageSource fontImageSource: FormsHandler.Warn($"loading placeholder from Font"); return DefaultFontImageSourcehandler.LoadImageAsync(fontImageSource); default: FormsHandler.Warn($"no valid placeholder found"); return null; } }
Как видите, ничего сложного в этом методе нет. В зависимости от типа заполнителя, установленного в классе FormsHandler
, мы вызываем реализацию по умолчанию Xamarin.Forms
для изображения-заполнителя. Давайте применим этот код, изменив LoadImageAsync
метод ImageSourceHandler
:
public async Task<UIImage> LoadImageAsync( ImageSource imageSource, CancellationToken cancellationToken = new CancellationToken(), float scale = 1) { var result = await NukeHelper.LoadViaNuke(imageSource, cancellationToken, scale); if (result == null) result = await LoadPlaceholderAsync(); return result; }
Поскольку нам нужно знать, может ли класс Nukehelper
загрузить изображение, мы уже запускаем код, ожидая его на этом уровне. Если результат равен нулю, мы загружаем изображение-заполнитель с помощью нашего ранее реализованного метода. Это все, что нам нужно сделать в нашем разветвленном репозитории Xamarin.Forms.Nuke
.
Как использовать его в своем проекте Xamarin.Forms - iOS
Сначала клонируйте мою вилку (или, если хотите) репозитория Xamarin.Forms.Nuke
, импортируйте ее в свое решение Xamarin.Forms
и ссылайтесь на нее в своем проекте iOS. Как только это будет сделано, нам нужно инициализировать библиотеку Nuke (как в исходном коде) в методе AppDelegate
‘s FinishedLaunching
:
Xamarin.Forms.Nuke.FormsHandler.Init(true, false);
Второй шаг - определить источник изображения-заполнителя. FontImageSource
следует определять после LoadApplication
метода. Таким образом вы можете Xamarin.Forms
загрузить шрифт как ресурс.
//Resource image Xamarin.Forms.Nuke.FormsHandler.PlaceholderFromResource("CachedImageTest.MSicc_Logo_Base_Blue_1024px_pad25.png", Assembly.GetAssembly(typeof(MainViewModel))); //FontImageSource Xamarin.Forms.Nuke.FormsHandler.PlaceholderFromFontImageSource(new FontImageSource { Glyph = CachedImageTest.Resources.MaterialDesignIcons.ImageBroken, FontFamily = "MaterialDesignIcons", Color = Color.Red });
Теперь используйте элемент управления Xamarin.Forms
Image
, как всегда. Если изображение из Интернета не может быть загружено, вы увидите заполнитель, как в этих двух примерах:
С помощью нескольких дополнений к библиотеке Xamarin.Forms.Nuke
мы реализовали механизм заполнителя для изображений, которые не могут быть загружены. Как всегда, я надеюсь, что этот пост будет полезен для некоторых из вас. Теперь, когда у меня есть реализация для iOS быстрого кэширования изображения с загрузкой заполнителя, я перейду к Android, где я попытаюсь добиться того же с помощью библиотеки Glidex.Forms и расширить ее, чтобы загрузить заполнитель. После реализации будет и полный образец. Следите за новостями!
До следующей публикации, желаю всем счастливого кодирования!
Сообщение Расширение Xamarin.Forms.Nuke на iOS для загрузки заполнителя для изображений, которые не загружаются впервые появилось в Блоге MSicc.