我正在尝试在RecyclerView中加载Youtube视频缩略图.我正面临一些问题.
这是我在适配器中正在做的事情:
public static class ItemViewHolder extends RecyclerView.ViewHolder { private YouTubeThumbnailView thumb; public Post post; public ItemViewHolder(View v) { thumb = (YouTubeThumbnailView) v.findViewById(R.id.youtube_thumbnail); } @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { if (holder instanceof ItemViewHolder) { ((ItemViewHolder) holder).thumb.initialize(YOUTUPEKEY, new YouTubeThumbnailView.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) { youTubeThumbnailLoader.setVideo(VIDEOID); } @Override public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) { }}); }}}
它工作正常,但我不是我做得对.当我在另一个活动中使用相同的适配器时,我收到此错误:
Activity com.example.yasser.version6.Mespublications has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@4252bcb8 that was originally bound here
加载缩略图需要时间,有时在滑动时会在它们之间混合.
我添加了一个函数来释放所有Youtube加载器:
public void ReleaseLoaders() { for (YouTubeThumbnailLoader loader : loaders.values()) { loader.release(); } }
我从Activity Onstop()调用此函数:
@Override public void onStop() { super.onStop(); mAdapter.ReleaseLoaders(); }
它运行良好一段时间,但有时崩溃.
你可以尝试这个吗?它没有使用API,但它很快.
使用此URL中的Picasso在Recycler视图中加载图像:
https://img.youtube.com/vi/ "这里是你的视频ID"/default.jpg
- 编辑 -
经过一些研究和实验:
要获取默认的完整大小缩略图,请执行此操作而不是default.jpg
https://img.youtube.com/vi/ "这里是你的视频ID"/0.jpg
这是链接:http://www.reelseo.com/youtube-thumbnail-image/
编辑2:
刚刚发现SO中的某个人已经通过这个快速简便的解决方案给出了我的答案,并提供了更多解释和选项供您选择.
如何从YouTube API获取YouTube视频缩略图?
最终编辑:
这是工作代码.我最近用api进了一个应用程序,所以我发现了你为什么会收到这个错误.这是因为你没有正确释放装载机.
您可以通过两种方式释放装载机/装载机.
第一
(首选,您将在一秒内看到原因)您希望在将图像加载到视图中之后释放它,并且该视图的侦听器和它的名为OnThumbNailLoadedListener.这就是我发布它的地方(如果你注意下面的代码).这意味着你不必再处理这个实例了.加载缩略图后,您就完成了.
第二
由于getView()始终被调用,因此您必须释放新的YouTubeThumbnailLoader实例.这意味着您必须将所有这些存储在ArrayList中.当活动为onStop()时,你只需要在所有这些循环中调用释放;
现在你可能会明白为什么第一种方式是首选.而且我知道你做了第二个选项,所以只是让你知道第一个选项将始终保证有效(至少在我的情况下).我在一个Activity中使用了YouTubeSupportFragment,它运行正常.没有任何问题.你绝对可以使第二个选项工作,但你必须处理我认为的许多特殊情况.
final YouTubeThumbnailView youTubeThumbnailView = (YouTubeThumbnailView) convertView.findViewById(R.id.show_episode_thumbnail); youTubeThumbnailView.initialize(DeveloperKey.DEVELOPER_KEY, new YouTubeThumbnailView.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) { youTubeThumbnailLoader.setVideo(videoId); youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() { @Override public void onThumbnailLoaded(YouTubeThumbnailView youTubeThumbnailView, String s) { youTubeThumbnailLoader.release(); } @Override public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) { } }); } @Override public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) { } });
在onBindViewHolder
您尝试反复初始化相同的内容YoutubeThumbnailView
时,您可以在创建视图时初始化它一次onCreateViewHolder
.通过将视频ID设置为标签,YoutubeThumbnailView
您可以防止混合(或)错误加载缩略图.
适配器.
private class ThumbnailAdapter extends RecyclerView.Adapter{ private final int UNINITIALIZED = 1; private final int INITIALIZING = 2; private final int INITIALIZED = 3; private int blackColor = Color.parseColor("#FF000000"); private int transparentColor = Color.parseColor("#00000000"); public class VideoViewHolder extends RecyclerView.ViewHolder{ public YouTubeThumbnailView ytThubnailView = null; public ImageView ivYtLogo = null; public TextView tvTitle = null; public VideoViewHolder(View itemView) { super(itemView); ytThubnailView = (YouTubeThumbnailView) itemView.findViewById(R.id.yt_thumbnail); ivYtLogo = (ImageView) itemView.findViewById(R.id.iv_yt_logo); tvTitle = (TextView) itemView.findViewById(R.id.tv_title); initialize(); } public void initialize(){ ivYtLogo.setBackgroundColor(blackColor); ytThubnailView.setTag(R.id.initialize, INITIALIZING); ytThubnailView.setTag(R.id.thumbnailloader, null); ytThubnailView.setTag(R.id.videoid, ""); ytThubnailView.initialize(API_KEY, new YouTubeThumbnailView.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) { ytThubnailView.setTag(R.id.initialize, INITIALIZED); ytThubnailView.setTag(R.id.thumbnailloader, youTubeThumbnailLoader); youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() { @Override public void onThumbnailLoaded(YouTubeThumbnailView youTubeThumbnailView, String loadedVideoId) { String currentVideoId = (String) ytThubnailView.getTag(R.id.videoid); if(currentVideoId.equals(loadedVideoId)) { ivYtLogo.setBackgroundColor(transparentColor); } else{ ivYtLogo.setBackgroundColor(blackColor); } } @Override public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) { ivYtLogo.setBackgroundColor(blackColor); } }); String videoId = (String) ytThubnailView.getTag(R.id.videoid); if(videoId != null && !videoId.isEmpty()){ youTubeThumbnailLoader.setVideo(videoId); } } @Override public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) { ytThubnailView.setTag(R.id.initialize, UNINITIALIZED); ivYtLogo.setBackgroundColor(blackColor); } }); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = getLayoutInflater().inflate(R.layout.row_video_item, parent, false); VideoViewHolder videoViewHolder = new VideoViewHolder(view); return videoViewHolder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final Entities e = entities.get(position); final VideoViewHolder videoViewHolder = (VideoViewHolder) holder; videoViewHolder.tvTitle.setText(e.name); videoViewHolder.ivYtLogo.setVisibility(View.VISIBLE); videoViewHolder.ytThubnailView.setTag(R.id.videoid, e.id); videoViewHolder.ivYtLogo.setBackgroundColor(blackColor); int state = (int) videoViewHolder.ytThubnailView.getTag(R.id.initialize); if(state == UNINITIALIZED){ videoViewHolder.initialize(); } else if(state == INITIALIZED){ YouTubeThumbnailLoader loader = (YouTubeThumbnailLoader) videoViewHolder.ytThubnailView.getTag(R.id.thumbnailloader); loader.setVideo(e.id); } } @Override public int getItemCount() { return entities.size(); } }
每行使用的布局是.
标签.xml.
位置:src/main/res/values/tags.xml