Hello,
According to your code, this is causing slow loading issues due to the fact that all the data has to be re-downloaded every time you click on the deck.
Here's how you could cache online images locally and avoid loading the same card multiple times.
First, Add the following property into Card class.
public string image_path { get; set; }
Use the following method for caching when loading images.
public async Task GetCardNamesAsync(string deckName)
{
CardList.Clear();
IsBusy = true;
var cards = await httpService.GetAsync<CardInfo>($"https://yugiohprices.com/api/set_data/{deckName}");
if (cards != null)
{
foreach (var card in cards.data.cards)
{
var encodedName = Uri.EscapeDataString(card.name);
var cardDetail = await httpService.GetAsync<CardDetail>(
$"https://db.ygoprodeck.com/api/v7/cardinfo.php?name={encodedName}");
card.id = cardDetail.Data.FirstOrDefault().Id;
card.description = cardDetail.Data.FirstOrDefault().Desc;
card.atk = cardDetail.Data.FirstOrDefault().Atk;
card.def = cardDetail.Data.FirstOrDefault().Def;
card.Race = cardDetail.Data.FirstOrDefault().Race;
card.Attribute = cardDetail.Data.FirstOrDefault().Attribute;
var path = Path.Combine(FileSystem.CacheDirectory, card.id.ToString() + ".jpg");
if (!File.Exists(path)) //Since cards are cached by ID, they will be directly changed to a local cache address when the same card is downloaded.
{
var file = File.Create(path);
file.Write(await httpService.GetByteArrayAsync(card.image_url));
}
card.image_path = path;
CardList.Add(card);
}
}
IsBusy = false;
}
Finally, use a local cache address for loading.
<Image
Margin="10"
Aspect="AspectFit"
MinimumHeightRequest="100"
MinimumWidthRequest="100"
Source="{Binding image_path}">
This is because your ActivityIndicator
as an EmptyView
. Therefore, when the first piece of data is added to the CardList
, the EmptyView
disappears, not because the isBusy
property does not take effect.
You can add a buffer list by adding data to the buffer list and then adding it to the CardList.
public ObservableCollection<Card> TempCardList { get; } = new ObservableCollection<Card>();
GetCardNamesAsync method:
public async Task GetCardNamesAsync(string deckName)
{
CardList.Clear();
IsBusy = true;
var cards = await httpService.GetAsync<CardInfo>($"https://yugiohprices.com/api/set_data/{deckName}");
if (cards != null)
{
foreach (Card card in cards.data.cards)
{
var encodedName = Uri.EscapeDataString(card.name);
var cardDetail = await httpService.GetAsync<CardDetail>(
$"https://db.ygoprodeck.com/api/v7/cardinfo.php?name={encodedName}");
card.id = cardDetail.Data.FirstOrDefault().Id;
card.description = cardDetail.Data.FirstOrDefault().Desc;
card.atk = cardDetail.Data.FirstOrDefault().Atk;
card.def = cardDetail.Data.FirstOrDefault().Def;
card.Race = cardDetail.Data.FirstOrDefault().Race;
card.Attribute = cardDetail.Data.FirstOrDefault().Attribute;
var path = Path.Combine(FileSystem.CacheDirectory, card.id.ToString() + ".jpg");
if (!File.Exists(path))
{
var file = File.Create(path);
file.Write(await httpService.GetByteArrayAsync(card.image_url));
}
card.image_path = path;
TempCardList.Add(card);
}
}
foreach (Card card in TempCardList)
{
CardList.Add(card);
}
IsBusy = false;
}
Best Regards,
Alec Liu.
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.