我正在尝试创建填充了youtube视频缩略图的GridView。
我使用异步任务模式类
包装了YouTubeThumbnailLoaderinterface IThumbnailLoader
{
Task<Drawable> LoadVideoThumbnailAsync(string id);
}
/// <summary>
/// Class to load youtube stuff
/// </summary>
class YoutubeThumbnailLoader : Java.Lang.Object, YouTubeThumbnailView.IOnInitializedListener, IThumbnailLoader
{
private YouTubeThumbnailView thumbnailView;
private IYouTubeThumbnailLoader thumbnailLoader;
TaskCompletionSource<IYouTubeThumbnailLoader> _tcsLoaderInitializated;
public YoutubeThumbnailLoader()
{
_tcsLoaderInitializated = new TaskCompletionSource<IYouTubeThumbnailLoader>();
}
public async Task InitializeAsync(Context context)
{
...
}
public async Task<Drawable> LoadVideoThumbnailAsync(string id)
{
try
{
MvxTrace.TaggedTrace("YoutubeThumbnailLoader.LoadVideoThumbnailAsync", "Started load task for id {0}", id);
TaskCompletionSource<Drawable> tcsImageLoaded = new TaskCompletionSource<Drawable>();
//TODO: unsure about that
thumbnailLoader.SetOnThumbnailLoadedListener(null);
thumbnailLoader.SetOnThumbnailLoadedListener(new ThumbnailListener(this, tcsImageLoaded));
string fid = ClearUrl(id);
thumbnailLoader.SetVideo(fid);
return await tcsImageLoaded.Task.ConfigureAwait(false);
}
catch (Exception ex)
{
MvxTrace.Trace(ex.ToString());
throw;
}
}
private string ClearUrl(string id)
{
...
}
~YoutubeThumbnailLoader()
{
if (thumbnailLoader != null)
{
thumbnailLoader.Release();
}
}
public void OnInitializationFailure(YouTubeThumbnailView thumbnailView, YouTubeInitializationResult errorReason)
{
...
}
public void OnInitializationSuccess(YouTubeThumbnailView p0, IYouTubeThumbnailLoader thumbnailLoader)
{
...
}
/// <summary>
/// An internal listener which listens to thumbnail loading events from the
/// YouTubeThumbnailView.
/// </summary>
private sealed class ThumbnailListener : Java.Lang.Object, IYouTubeThumbnailLoaderOnThumbnailLoadedListener
{
private YoutubeThumbnailLoader youtubeThumbnailLoader;
private TaskCompletionSource<Drawable> tcs;
public ThumbnailListener(YoutubeThumbnailLoader youtubeThumbnailLoader, TaskCompletionSource<Drawable> tcsImageLoaded)
{
this.youtubeThumbnailLoader = youtubeThumbnailLoader;
this.tcs = tcsImageLoaded;
}
public void OnThumbnailError(YouTubeThumbnailView thumbnail, YouTubeThumbnailLoaderErrorReason reason)
{
MvxTrace.Trace("Thumbnail listener Error: " + reason.ToString());
tcs.SetException(new YoutubeThumbnailException(reason));
}
public void OnThumbnailLoaded(YouTubeThumbnailView thumbnail, string videoId)
{
MvxTrace.Trace("Thumbnail listener loaded: " + videoId);
tcs.SetResult(thumbnail.Drawable);
}
}
internal async static Task<IThumbnailLoader> CreateLoader(Context context)
{
var me = new YoutubeThumbnailLoader();
await me.InitializeAsync(context);
return me;
}
}
当我使用这个类来填充简单的'ImageView'时,效果很好:
public override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
var ld = await YoutubeThumbnailLoader.CreateLoader(this.Activity);
_iv.SetImageDrawable(await ld.LoadVideoThumbnailAsync("sFSesoqjNn8"));
_iv2.SetImageDrawable(await ld.LoadVideoThumbnailAsync("sFSesoqjNn8"));
_gridView.Adapter = new Adapters.CustomGridViewAdapter(ld, Activity, (IMvxAndroidBindingContext)BindingContext);
}
但在我的自定义适配器中它根本不起作用。这是
class CustomGridViewAdapter : MvxAdapter
{
private Helpers.IThumbnailLoader _ytl;
public CustomGridViewAdapter(Helpers.IThumbnailLoader ytl, Context context, IMvxAndroidBindingContext bindingContext)
: base(context, bindingContext)
{
_ytl = ytl;
}
async Task SetImageView(string id, ImageView iv)
{
var dr = await _ytl.LoadVideoThumbnailAsync(id);
MvxTrace.TaggedTrace("CustomGridViewAdapter.GetView", "loaded some item {0}", dr.ToString());
iv.SetImageDrawable(dr);
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = ((Activity)base.Context).LayoutInflater;
var rowView = inflater.Inflate(Resource.Layout.item_video_wall, parent, false);
ImageView imageView = rowView.FindViewById<ImageView>(Resource.Id.imageView1);
var bb = (YouTubeVideoTag)GetRawItem(position);
MvxTrace.TaggedTrace("CustomGridViewAdapter.GetView", "Prepared to load '{0}' item into position {1}", bb.VideoUrl, position);
SetImageView(bb.VideoUrl, imageView);
return rowView;
}
我认为这个调用应该保存当前的'ImageView'指针并将其设置为可绘制的,但这不起作用,我不明白为什么。
SetImageView(bb.VideoUrl, imageView);
任何帮助?
答案 0 :(得分:0)
问题在于
TaskCompletionSource<Drawable> tcsImageLoaded = new TaskCompletionSource<Drawable>();
//TODO: unsure about that
thumbnailLoader.SetOnThumbnailLoadedListener(null);
thumbnailLoader.SetOnThumbnailLoadedListener(new ThumbnailListener(this, tcsImageLoaded));
我甚至在任务完成之前替换了听众。
我重写了这段代码并为每个GridView
项目
if (holder.Image != null)
{
var bb = (YouTubeVideoTag)GetRawItem(position);
MvxTrace.TaggedTrace("CustomGridViewAdapter.GetView", "Prepared to load '{0}' item into position {1}", bb.VideoUrl, position);
(new ImageSetAsyncWorker(base.Context, holder.Image)).SetImageView(bb.VideoUrl);
}
我不确定这是使用YouTubeThumbnailLoader
的正确方法,但它有效。
public async Task SetImageView(string id)
{
var loader = await Helpers.YoutubeThumbnailLoader.CreateLoader(_context);
var dr = await loader.LoadVideoThumbnailAsync(id);
MvxTrace.TaggedTrace("CustomGridViewAdapter.GetView", "loaded some item {0}", dr.ToString());
ImageView iv;
if (_wr.TryGetTarget(out iv))
{
iv.SetImageDrawable(dr);
}
}