2015-12-19 18 views
19

Tôi đang cố tải hình thu nhỏ video Youtube trong RecyclerView. Tôi đang đối mặt với một số vấn đề.Cách tải hình thu nhỏ Youtube trong RecyclerView bằng cách sử dụng Youtube API

Đây là những gì tôi đang làm ở bộ chuyển đổi của tôi:

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) { 

       }}); 
}}} 

Nó hoạt động tốt, nhưng tôi không tôi đang làm điều đó đúng. Khi tôi đang sử dụng bộ chuyển đổi tương tự trong hoạt động khác tôi nhận được lỗi này:

Activity com.example.yasser.version6.Mespublications has leaked ServiceConnection [email protected] that was originally bound here 

và phải mất thời gian để tải hình thu nhỏ và đôi khi nó trộn giữa chúng khi trượt.

Tôi đã thêm một chức năng để giải phóng tất cả các Máy bốc Youtube:

public void ReleaseLoaders() { 
    for (YouTubeThumbnailLoader loader : loaders.values()) { 
     loader.release(); 
    } 
} 

và tôi đang gọi chức năng này từ Hoạt động Onstop():

@Override 
public void onStop() { 
    super.onStop(); 
    mAdapter.ReleaseLoaders(); 
} 

Nó hoạt động tốt trong một thời gian, nhưng đôi khi bị treo.

+0

có bạn kiểm tra [này SO vé] (http://stackoverflow.com/questions/1992676/i-cant -get-rid-of-này-lỗi-tin-hoạt động-ứng dụng-tên-đã bị rò rỉ-servicecon)? Dường như có cùng một vấn đề mà bạn đang gặp phải - bộ nhớ bị rò rỉ, không phải là RecyclerView, có vẻ như bạn đã xử lý nó rồi. – adjuremods

+0

Lỗi đến từ bộ điều hợp Recylcerview –

+0

Làm cách nào để khởi tạo bộ điều hợp của bạn? – random

Trả lời

26

Bạn có thể thử này có thể? Nó không sử dụng API nhưng nó nhanh chóng.

tải hình ảnh trong giao diện tái chế với Picasso từ URL này:

https://img.youtube.com/vi/ "ở đây đi id video của bạn" /default.jpg

- Edit -

Sau khi một số nghiên cứu và thử nghiệm:

Để có hình thu nhỏ kích thước đầy đủ mặc định làm điều này thay vì default.jpg

https://img.youtube.com/vi/ "ở đây đi id video của bạn"/0.jpg

Dưới đây là liên kết: http://www.reelseo.com/youtube-thumbnail-image/

Chỉnh sửa 2:

Chỉ cần thấy ai đó trong SO đã đưa ra một câu trả lời như tôi với giải pháp này nhanh chóng và dễ dàng và có cách giải thích thêm và các tùy chọn bạn có thể chọn từ .

How do I get a YouTube video thumbnail from the YouTube API?


cuối cùng Edit:

Đây là mã làm việc. Tôi đã đi vào và thực hiện một ứng dụng gần đây với api vì vậy tôi phát hiện ra lý do tại sao bạn nhận được lỗi. Bởi vì bạn không phát hành bộ nạp đúng cách.

Bạn có thể phát hành bộ nạp/bộ nạp theo hai cách.

Đầu tiên

(Preferred, bạn sẽ thấy lý do tại sao trong một giây) Bạn sẽ muốn phát hành nó sau khi hình ảnh đã được nạp vào xem và theres một người biết lắng nghe cho điều đó và gọi OnThumbNailLoadedListener của nó. Đó là nơi tôi phát hành nó (nếu bạn chú ý đến mã bên dưới). Điều này có nghĩa là bạn không phải đối phó với trường hợp này nữa. Khi hình thu nhỏ được tải xong, bạn đã hoàn tất.

Second

Kể từ getView() được gọi tất cả các thời gian có trường hợp mới của YouTubeThumbnailLoader mà bạn có để phát hành. Điều này có nghĩa là bạn phải lưu trữ tất cả chúng trong một ArrayList. Bạn chỉ cần thực hiện một nâng cao cho vòng lặp và phát hành cuộc gọi trong tất cả chúng khi hoạt động là onStop();

Bây giờ bạn có thể thấy lý do tại sao cách đầu tiên được ưu tiên. Và tôi biết bạn đã làm tùy chọn thứ hai để chỉ cho bạn biết tùy chọn đầu tiên sẽ luôn được đảm bảo hoạt động (ít nhất là trong trường hợp của tôi). Tôi đã sử dụng YouTubeSupportFragment trong một Hoạt động và nó hoạt động tốt. Không có vấn đề gì. Bạn chắc chắn có thể làm cho tùy chọn thứ hai làm việc nhưng bạn sẽ phải xử lý rất nhiều trường hợp đặc biệt tôi nghĩ.

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) { 

     } 
    }); 
+0

Đây là lựa chọn tốt nhất! cảm ơn –

+0

Chỉ cần thực hiện chỉnh sửa tốt cho câu trả lời của tôi. Tôi đề nghị bạn hãy xem. –

+0

Cảm ơn rất nhiều dude .. !! –

11

Trong onBindViewHolder bạn đang cố gắng khởi tạo cùng một YoutubeThumbnailView một lần nữa và một lần nữa, thay vào đó bạn có thể khởi tạo nó một lần khi chế độ xem được tạo trong onCreateViewHolder. Bằng cách đặt Id video làm thẻ thành số YoutubeThumbnailView, bạn có thể ngăn việc trộn (hoặc) tải hình thu nhỏ sai.


Bộ điều hợp.

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(); 
    } 
} 

Việc bố trí sử dụng cho mỗi hàng là.

<?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.

Location: 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> 

enter image description here

+0

Cảm ơn bạn đã phản hồi, Nhưng tôi đã thử nó và Hình thu nhỏ vẫn đang trộn! –

+0

Tôi đang sử dụng nó trong ứng dụng của mình. Nó hoạt động tốt. Hình thu nhỏ sẽ không nhận được Mixed Up. –

0

public class VideoAdapter kéo dài RecyclerView.Adapter {

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; 
} 

}

Các vấn đề liên quan