如何使用 Youtube 在 RecyclerView 中加载 Youtube 缩略图 API
How to load Youtube thumbnails in a RecyclerView using Youtube API
我正在尝试在 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 中使用相同的适配器时,我收到此错误:
Activity com.example.yasser.version6.Mespublications has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@4252bcb8 that was originally bound here
加载缩略图需要时间,有时滑动时它们会混在一起。
我添加了释放所有 Youtube Loader 的功能:
public void ReleaseLoaders() {
for (YouTubeThumbnailLoader loader : loaders.values()) {
loader.release();
}
}
我从 Activity Onstop() 调用这个函数:
@Override
public void onStop() {
super.onStop();
mAdapter.ReleaseLoaders();
}
有一段时间它运行良好,但有时会崩溃。
在 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 version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<com.google.android.youtube.player.YouTubeThumbnailView
android:id="@+id/yt_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/iv_yt_logo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@mipmap/youtube_play"
android:background="#00000000"
android:layout_centerInParent="true"/>
</RelativeLayout>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:textSize="16sp"
android:text="Title"/>
<View
android:id="@+id/seperator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="#FF642108"/>
</LinearLayout>
tags.xml.
位置:src/main/res/values/tags.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="initialize" />
<item type="id" name="videoid"/>
<item type="id" name="thumbnailloader"/>
</resources>
你可以试试这个吗?它不使用 API 但它很快。
使用毕加索在回收站视图中加载图片 URL:
https://img.youtube.com/vi/"here goes your video id"/default.jpg
-- 编辑--
经过一些研究和实验:
要获得默认的全尺寸缩略图,请执行此操作而不是 default.jpg
https://img.youtube.com/vi/"here goes your video id"/0.jpg
这里是link:http://www.reelseo.com/youtube-thumbnail-image/
编辑 2:
刚刚发现 SO 中的某个人已经用这个快速简单的解决方案给出了像我这样的答案,并且有更多的解释和选项供您选择。
How do I get a YouTube video thumbnail from the YouTube API?
最终编辑:
这是工作代码。我最近使用 api 制作了一个应用程序,所以我发现了您收到错误的原因。这是因为您没有正确释放装载机。
您可以通过两种方式释放loader/loaders。
第一
(首选,稍后你会明白为什么)
您可能希望在图像加载到视图中后释放它,并且有一个侦听器及其名为 OnThumbNailLoadedListener 的侦听器。那就是我发布它的地方(如果你注意下面的代码)。这意味着您不必再处理这个实例。加载缩略图后就大功告成了。
第二
由于一直调用 getView(),因此您必须发布新的 YouTubeThumbnailLoader 实例。这意味着您必须将所有这些存储在一个 ArrayList 中。当 activity 为 onStop();
时,您只需执行高级 for 循环并在所有循环中调用 release
现在您可能明白为什么首选第一种方法了。而且我知道您选择了第二个选项,所以只要让您知道第一个选项将始终保证有效(至少在我的情况下)。我在 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) {
}
});
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder> {
private List<VideoPojo> listvideo;
private VideoPojo videoPojo;
private Context mContext;
private boolean readyForLoadingYoutubeThumbnail = true;
String KEY = "AIzaSyA5kyaLgS7MKxS19uHf2CUsIOmDkv92DGU";
public VideoAdapter(Context context, List<VideoPojo> listvideo) {
this.listvideo = listvideo;
this.mContext = context;
videoPojo = new VideoPojo();
}
@Override
public VideoAdapter.VideoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_layout, parent, false);
return new VideoHolder(view);
}
@Override
public void onBindViewHolder(final VideoAdapter.VideoHolder holder, final int position) {
holder.murl.setText(listvideo.get(position).getVideoUrl());
final String url = listvideo.get(position).getVideoUrl();
Log.d(TAG, "readyForLoadingYoutubeThumbnail" + readyForLoadingYoutubeThumbnail);
if (readyForLoadingYoutubeThumbnail) {
Log.d(TAG, "initializing for youtube thumbnail view...");
readyForLoadingYoutubeThumbnail = false;
holder.youTubeThumbnailView.initialize(KEY, new YouTubeThumbnailView.OnInitializedListener() {
@Override
public void onInitializationSuccess(final YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) {
youTubeThumbnailLoader.setVideo(url);
youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() {
@Override
public void onThumbnailLoaded(YouTubeThumbnailView childYouTubeThumbnailView, String s) {
holder.loding.setVisibility(View.GONE);
youTubeThumbnailLoader.release(); // spy ga memory lick
}
@Override
public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
youTubeThumbnailLoader.release(); // spy ga memory lick
}
});
readyForLoadingYoutubeThumbnail = true;
}
@Override
public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
//do nohing.. ada error, tambahin method ini jalan, error-nya lupa...
readyForLoadingYoutubeThumbnail = true;
}
});
}
holder.mdelate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deleteVideoAlertDialog(listvideo.get(holder.getAdapterPosition()).getId(), holder.getAdapterPosition());
}
});
}
@Override
public int getItemCount() {
// Log.v(VideoAdapter.class.getSimpleName(), "" + listvideo.size());
return listvideo.size();
}
public class VideoHolder extends RecyclerView.ViewHolder {
YouTubeThumbnailView youTubeThumbnailView;
protected FrameLayout playButton;
TextView murl, mdelate;
ImageView loding;
public VideoHolder(View itemView) {
super(itemView);
mdelate = itemView.findViewById(R.id.mdelate);
murl = itemView.findViewById(R.id.murl);
playButton = itemView.findViewById(R.id.btnYoutube_player);
youTubeThumbnailView = itemView.findViewById(R.id.youtube_thumbnail);
loding = itemView.findViewById(R.id.loding);
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = getAdapterPosition();
String url = listvideo.get(position).getVideoUrl();
Toast.makeText(mContext, url, Toast.LENGTH_SHORT).show();
Intent intent = YouTubeStandalonePlayer.createVideoIntent((Activity) mContext,
KEY, url, 100, false, true);
mContext.startActivity(intent);
}
});
}
}
private void deleteVideoAlertDialog(final int row_id, final int adapterPosition) {
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("Delete");
// Setting Dialog Message
alertDialog.setMessage("Are you sure you want to delete this video");
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (SQLiteHelper.deleteUser(mContext, row_id)) {
listvideo.remove(adapterPosition);
notifyItemRemoved(adapterPosition);
notifyItemRangeChanged(adapterPosition, listvideo.size());
} else {
Toast.makeText(mContext, "internal issue ", Toast.LENGTH_SHORT).show();
}
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
public boolean addNewVideo(String Url, Context context) {
videoPojo.setVideoUrl(Url);
SQLiteHelper sqLiteHelper = new SQLiteHelper(context);
if (sqLiteHelper.addNewVideo(context, videoPojo)) {
listvideo.add(videoPojo);
notifyDataSetChanged();
Toast.makeText(context, "video Saved", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
}
从此 URL 获得高质量图像:
https://img.youtube.com/vi/<VIDEO_ID_HERE>/maxresdefault.jpg
然后使用 picasso 或 glide 库加载它。
对于此视频“https://www.youtube.com/watch?v=BEScHJrjsmU”,VIDEO_ID 是 "BEScHJrjsmU"
我正在尝试在 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 中使用相同的适配器时,我收到此错误:
Activity com.example.yasser.version6.Mespublications has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@4252bcb8 that was originally bound here
加载缩略图需要时间,有时滑动时它们会混在一起。
我添加了释放所有 Youtube Loader 的功能:
public void ReleaseLoaders() {
for (YouTubeThumbnailLoader loader : loaders.values()) {
loader.release();
}
}
我从 Activity Onstop() 调用这个函数:
@Override
public void onStop() {
super.onStop();
mAdapter.ReleaseLoaders();
}
有一段时间它运行良好,但有时会崩溃。
在 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 version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<com.google.android.youtube.player.YouTubeThumbnailView
android:id="@+id/yt_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/iv_yt_logo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@mipmap/youtube_play"
android:background="#00000000"
android:layout_centerInParent="true"/>
</RelativeLayout>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:textSize="16sp"
android:text="Title"/>
<View
android:id="@+id/seperator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="#FF642108"/>
</LinearLayout>
tags.xml.
位置:src/main/res/values/tags.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="initialize" />
<item type="id" name="videoid"/>
<item type="id" name="thumbnailloader"/>
</resources>
你可以试试这个吗?它不使用 API 但它很快。
使用毕加索在回收站视图中加载图片 URL:
https://img.youtube.com/vi/"here goes your video id"/default.jpg
-- 编辑--
经过一些研究和实验:
要获得默认的全尺寸缩略图,请执行此操作而不是 default.jpg
https://img.youtube.com/vi/"here goes your video id"/0.jpg
这里是link:http://www.reelseo.com/youtube-thumbnail-image/
编辑 2:
刚刚发现 SO 中的某个人已经用这个快速简单的解决方案给出了像我这样的答案,并且有更多的解释和选项供您选择。
How do I get a YouTube video thumbnail from the YouTube API?
最终编辑:
这是工作代码。我最近使用 api 制作了一个应用程序,所以我发现了您收到错误的原因。这是因为您没有正确释放装载机。
您可以通过两种方式释放loader/loaders。
第一
(首选,稍后你会明白为什么) 您可能希望在图像加载到视图中后释放它,并且有一个侦听器及其名为 OnThumbNailLoadedListener 的侦听器。那就是我发布它的地方(如果你注意下面的代码)。这意味着您不必再处理这个实例。加载缩略图后就大功告成了。
第二
由于一直调用 getView(),因此您必须发布新的 YouTubeThumbnailLoader 实例。这意味着您必须将所有这些存储在一个 ArrayList 中。当 activity 为 onStop();
时,您只需执行高级 for 循环并在所有循环中调用 release现在您可能明白为什么首选第一种方法了。而且我知道您选择了第二个选项,所以只要让您知道第一个选项将始终保证有效(至少在我的情况下)。我在 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) {
}
});
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder> {
private List<VideoPojo> listvideo;
private VideoPojo videoPojo;
private Context mContext;
private boolean readyForLoadingYoutubeThumbnail = true;
String KEY = "AIzaSyA5kyaLgS7MKxS19uHf2CUsIOmDkv92DGU";
public VideoAdapter(Context context, List<VideoPojo> listvideo) {
this.listvideo = listvideo;
this.mContext = context;
videoPojo = new VideoPojo();
}
@Override
public VideoAdapter.VideoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_layout, parent, false);
return new VideoHolder(view);
}
@Override
public void onBindViewHolder(final VideoAdapter.VideoHolder holder, final int position) {
holder.murl.setText(listvideo.get(position).getVideoUrl());
final String url = listvideo.get(position).getVideoUrl();
Log.d(TAG, "readyForLoadingYoutubeThumbnail" + readyForLoadingYoutubeThumbnail);
if (readyForLoadingYoutubeThumbnail) {
Log.d(TAG, "initializing for youtube thumbnail view...");
readyForLoadingYoutubeThumbnail = false;
holder.youTubeThumbnailView.initialize(KEY, new YouTubeThumbnailView.OnInitializedListener() {
@Override
public void onInitializationSuccess(final YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) {
youTubeThumbnailLoader.setVideo(url);
youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() {
@Override
public void onThumbnailLoaded(YouTubeThumbnailView childYouTubeThumbnailView, String s) {
holder.loding.setVisibility(View.GONE);
youTubeThumbnailLoader.release(); // spy ga memory lick
}
@Override
public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
youTubeThumbnailLoader.release(); // spy ga memory lick
}
});
readyForLoadingYoutubeThumbnail = true;
}
@Override
public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
//do nohing.. ada error, tambahin method ini jalan, error-nya lupa...
readyForLoadingYoutubeThumbnail = true;
}
});
}
holder.mdelate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deleteVideoAlertDialog(listvideo.get(holder.getAdapterPosition()).getId(), holder.getAdapterPosition());
}
});
}
@Override
public int getItemCount() {
// Log.v(VideoAdapter.class.getSimpleName(), "" + listvideo.size());
return listvideo.size();
}
public class VideoHolder extends RecyclerView.ViewHolder {
YouTubeThumbnailView youTubeThumbnailView;
protected FrameLayout playButton;
TextView murl, mdelate;
ImageView loding;
public VideoHolder(View itemView) {
super(itemView);
mdelate = itemView.findViewById(R.id.mdelate);
murl = itemView.findViewById(R.id.murl);
playButton = itemView.findViewById(R.id.btnYoutube_player);
youTubeThumbnailView = itemView.findViewById(R.id.youtube_thumbnail);
loding = itemView.findViewById(R.id.loding);
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = getAdapterPosition();
String url = listvideo.get(position).getVideoUrl();
Toast.makeText(mContext, url, Toast.LENGTH_SHORT).show();
Intent intent = YouTubeStandalonePlayer.createVideoIntent((Activity) mContext,
KEY, url, 100, false, true);
mContext.startActivity(intent);
}
});
}
}
private void deleteVideoAlertDialog(final int row_id, final int adapterPosition) {
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("Delete");
// Setting Dialog Message
alertDialog.setMessage("Are you sure you want to delete this video");
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (SQLiteHelper.deleteUser(mContext, row_id)) {
listvideo.remove(adapterPosition);
notifyItemRemoved(adapterPosition);
notifyItemRangeChanged(adapterPosition, listvideo.size());
} else {
Toast.makeText(mContext, "internal issue ", Toast.LENGTH_SHORT).show();
}
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
public boolean addNewVideo(String Url, Context context) {
videoPojo.setVideoUrl(Url);
SQLiteHelper sqLiteHelper = new SQLiteHelper(context);
if (sqLiteHelper.addNewVideo(context, videoPojo)) {
listvideo.add(videoPojo);
notifyDataSetChanged();
Toast.makeText(context, "video Saved", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
}
从此 URL 获得高质量图像:
https://img.youtube.com/vi/<VIDEO_ID_HERE>/maxresdefault.jpg
然后使用 picasso 或 glide 库加载它。
对于此视频“https://www.youtube.com/watch?v=BEScHJrjsmU”,VIDEO_ID 是 "BEScHJrjsmU"