Отображение картинок
На этой страницу вы узнаете, как получить растровое изображения для каждого альбома из результатов поиска.
После этого, вы сможете отображать на картинку внутри тайла альбома во view
, вместо заглушки в виде иконки музыкальной ноты.
Album Service
Первым делом мы изменим бизнес-сервис, чтобы получать обложки альбомов через Web API Apple iTunes.
Выполните указанные ниже действия:
- Остановите приложение, если оно запущено.
- В папке /Models найдите и откройте файл Album.cs.
- Добавьте код, как показано ниже:
private static HttpClient s_httpClient = new();
private string CachePath => $"./Cache/{Artist} - {Title}";
public async Task<Stream> LoadCoverBitmapAsync()
{
if (File.Exists(CachePath + ".bmp"))
{
return File.OpenRead(CachePath + ".bmp");
}
else
{
var data = await s_httpClient.GetByteArrayAsync(CoverUrl);
return new MemoryStream(data);
}
}
Данный метод возвращает поток, который можно использовать для загрузки изображения из кэш-файла или API.
Обратите внимание, что на данный момент кэш недоступен, по руководству он будет реализован позже.
- Чтобы увидеть, когда кэш станет доступен, установите точку останова на указанной строке:
return File.OpenRead(CachePath + ".bmp");
View Model альбома
На данном этапе, вы добавите свойство для album view model
, чтобы сохранить обложку как растровое изображение.
Вы должны использовать ссылку на Avalonia.Media.Imaging
, поскольку album view model
должен использовать
растровое изображение Avalonia UI, а не System.Bitmap
из .NET.
Выполните указанные ниже действия:
- Найдите и откройте файл AlbumViewModel.cs.
- Добавьте ссылку на
using Avalonia.Media.Imaging;
. - Добавьте дополнительный код для обложки альбома, как показано ниже:
using Avalonia.Media.Imaging;
...
public class AlbumViewModel : ViewModelBase
{
...
private Bitmap? _cover;
public Bitmap? Cover
{
get => _cover;
private set => this.RaiseAndSetIfChanged(ref _cover, value);
}
public async Task LoadCover()
{
await using (var imageStream = await _album.LoadCoverBitmapAsync())
{
Cover = await Task.Run(() => Bitmap.DecodeToWidth(imageStream, 400));
}
}
}
Потратьте немного времени на изучения написанного кода, в нем описано манипулирование изображениями с помощью Avalonia UI.
К примеру, в приведенном выше примере используется метод DecodeToWidth
, который преобразует поток изображений для отображения через Avalonia UI.
Этот метод может преобразовать поток для изображения с высоким разрешением в растровое меньшего размера, с заданной шириной и сохранением соотношения сторон.
Это означает, что вы не будете тратить много памяти для отображения обложек альбомов, несмотря на то, что Web API возвращает довольно большие файлы.
Также обратите внимание на метод LoadCover
, он написан для асинхронного запуска в фоновом потоке.
Это делается для того, чтобы блокирова ть UI-поток, иначе UI будет зависать.
Загрузка обложек
На этом шаге, вы измените поиска альбома (в music store view model
) таким образом,
чтобы обложка загружалась для каждого найденного альбома.
Для сохранения отзывчивости приложения, вы сделаете этот процесс асинхронным, с возможностью его отмены.
Во-первых, вам необходимо добавить метод, который сможет запускать загрузку обложек альбомов при изменении результатов поиска. Вы сделаете его асинхронным и отменяемым.
Для добавления метода загрузки обложек альбомов, выполните указанные ниже действия:
- Найдите и откройте файл MusicStoreViewModel.cs.
- Добавьте код, как показано ниже:
private async void LoadCovers(CancellationToken cancellationToken)
{
foreach (var album in SearchResults.ToList())
{
await album.LoadCover();
if (cancellationToken.IsCancellationRequested)
{
return;
}
}
}
Вжное примечание: данный метод выполняет итерации по копии коллекции результатов поиска (создается методом ToList
).
Это связано с тем, что он выполняется асинхронно в другом потоке, а исходная коллекция может быть изменена другим поток в любое время.
Аргумент cancellation token (рус: токена отмены)
, позволит вам по необходимости отменить выполнение метода по загрузке обложек альбомов.