DataLoader
Helper class to simplify loading and caching data. Intended to use with ListView items to avoid problems with reusable instances.
Usage
public class ListViewImage : ListViewCustom<ImageItem, string>
{
public DataLoader<string, Sprite> Loader;
protected override void InitOnce()
{
base.InitOnce();
Loader = new DataLoader<string, Sprite>(async request =>
{
var web_request = UnityWebRequest.Get(request);
await web_request.SendWebRequest();
if (web_request.result != UnityWebRequest.Result.Success)
{
Debug.LogWarning(string.Format("UnityWebRequest Failed. URI: {0}; Result: {1}; Code: {2}; Content: {3}",
request, web_request.result, web_request.responseCode, web_request.downloadHandler.text));
return new Tuple<bool, Sprite>(false, null);
}
var texture = DownloadHandlerTexture.GetContent(web_request);
var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
return new Tuple<bool, Sprite>(true, sprite);
});
}
}
public class ImageItem : ListViewItem, IViewData<string>
{
public Image Image;
protected string Item;
protected DataLoader<string, Sprite> Loader => (Owner as ListViewImage).Loader;
public void SetData(string item)
{
Item = item;
UpdateView(item);
}
async void UpdateView(string url)
{
// reset image or show "loading" placeholder
Image.sprite = null;
// load sprite
var (success, sprite) = await Loader.GetAsync(url);
// if sprite was not loaded
if (!success)
{
return;
}
// check if item is still same (item will be different if ImageItem instance was recycled)
if (Item != url)
{
// do nothing
return;
}
Image.sprite = sprite;
}