水平ScrollView内有多个YouTubePlayerFragments-所有播放器都显示最后加载的视频 [英] Multiple YouTubePlayerFragments inside a Horizontal ScrollView - all the players display the last loaded video
问题描述
我想在水平ScrollView中显示多个YouTube视频.为此,我正在动态添加YouTubePlayerFragments.这是我的代码片段:
I want to show multiple YouTube videos in a Horizontal ScrollView. For that, I'm adding YouTubePlayerFragments dynamically. Here's the piece of my code:
//set videos
int count = 0;
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
for (final Video video : mVideos) {
//create an instance of a video fragment
final VideoFragment fragment = new VideoFragment();// VideoFragment extends YouTubePlayerFragment
Bundle bundle = new Bundle();
if (null != mVideos && 0 < mVideos.size()) {
bundle.putString(VideoFragment.KEY_VIDEO_KEY, video.getKey());
}
fragment.setArguments(bundle);
FrameLayout frameLayout = new FrameLayout(getActivity());
frameLayout.setLayoutParams(new FrameLayout.LayoutParams(900, 500));
frameLayout.setPadding(10, 0, 10, 0);
frameLayout.setId(12345 + ++count);
mLayoutTrailers.addView(frameLayout);//mLayoutTrailers is a LinearLayout inside my Horizontal ScrollView
transaction.add(frameLayout.getId(), fragment, VideoFragment.TAG + count);
}
transaction.commit();
我正在我的VideoFragment的OnResume中初始化youtube播放器.以下是视频的加载方式.
I'm initializing the youtube player inside OnResume of my VideoFragment. And below is how the videos gets loaded.
它显示了所有播放器的最后加载的视频.我进行了调试-使用第一个视频初始化所有播放器,然后使用第二个视频初始化所有播放器,直到最后一个.
It shows the lastly loaded video for all the players. I debugged - It initializes all the players with the first video, then all the players with the second video & so on until the last one.
The issue is already discussed here. There seems to be a work around with initializing the player inside "setUserVisibleHint(boolean isVisibleToUser)" in my VideoFragment in stead of OnResume(), but I don't know how to use that with my HorizontalScrollView
是否可以在水平ScrollView中加载多个YouTube视频?
任何帮助将不胜感激!
推荐答案
我认为无法创建YouTube播放器片段的多个实例,因为它是Singleton
.
I dont think it is possible to create multiple instance of YouTube Player Fragment as it is Singleton
.
无论您创建了多少个实例,它们都一样,并且水平滚动视图将显示您添加的最后一个VideoFragment的缩略图.
No matter how many instances you make they all gone be same and your horizontal scrollview will show thumbnail of last VideoFragment you added .
或者,您可以通过显示视频拇指并单击拇指来给出多个YouTube片段的幻觉,然后在youtube播放器的帮助下播放视频
Alternatively you can give an illusion of multiple YouTube Fragment by showing video thumb and on click of thumb play the video with the help of youtube player
// get thumbnail image of that video by videoID
String videoThumbUrl="http://img.youtube.com/vi/"+videoId+"/0.jpg";
//Load thumb in viewpager/Hrizontal scrollview/Recycle View with the
//help of Picasso/Glide/UIL etc
Picasso.with(getActivity())
.load(videoThumbUrl)
.into(videoThumbImageView);
然后点击一下拇指,您可以在包含imageview的View容器中添加youtube片段,然后开始播放带有视频ID的视频
And then on click of thumb you can add youtube fragment in View container holding imageview and start playing video with the video id
videoThumbImageView.setOnClickListenr(..)
{...
//Add Youtube fragment in container and start playing video
}
这只是一个伪代码,但是您会明白的.
This is just a pseudo code but you get and idea.
修改
添加了有关如何在点击缩略图时播放和停止视频的代码.
Added code for how to play and stop videos on tap of thumbnails.
我处于离线状态,因此无法使用YouTube片段,因此我使用Videoview播放随机视频,可以将videoview替换为YouTube片段,然后.保证它仍然可以很好地工作
I was offline so was unable to use YouTube fragment so I used Videoview to play random videos you can replace videoview with YouTube fragment and. Guranteed it still gone work great
用于保存视频列表的数组列表
Array list to hold list of videos
public static ArrayList<VideoModel> listOfVideos = new ArrayList<>();
可以跟踪当前播放的视频
Variable to keep track of current playing video
// Allows to remember the last item shown on screen
private int lastPosition = 0;
Recycler视图项单击侦听器
Recycler view item click listener
videoGridAdapter.setOnCardClickListner(new VideoGridAdapter.OnCardClickListner() {
@Override
public void OnCardClicked(View view, int position) {
//Make Lats Tapped item playing false
listOfVideos.get(lastPosition).setPlaying(false);
//Make current Tapped item playing true
listOfVideos.get(position).setPlaying(true);
// update pointer of last tapped video to current tapped video
lastPosition = position;
//LET RCYCLERVIEW ADAPTER DO THE MAGIC
videoGridAdapter.notifyDataSetChanged();
}
});
VideoModel类
VideoModel class
**
* Created by Hitesh on 20-07-2016.
*/
public class VideoModel {
public int getImageURLTest() {
return imageURLTest;
}
//Test Data
private int imageURLTest;
//Real Time Data
private String videoURL;
private String imageURL;
private boolean isPlaying;
public VideoModel(String videoURL, boolean isSelected, int imageURLTest) {
this.videoURL = videoURL;
this.isPlaying = isSelected;
this.imageURLTest = imageURLTest;
}
public boolean isPlaying() {
return isPlaying;
}
public void setPlaying(boolean playing) {
isPlaying = playing;
}
/**
* @return Youtube URl of Video
*/
public String getVideoURL() {
return videoURL;
}
/**
* @return Thumbnail of Video using video ID
*/
public String getImageURL() {
//Derive Image URl from Video URl using Video ID
return imageURL;
}
}
适配器本身
import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.hiteshsahu.videoinraw.R;
import com.hiteshsahu.videoinraw.ui.activity.VideoGridActivity;
import com.squareup.picasso.Callback;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
public class VideoGridAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private OnCardClickListner onCardClickListner;
public VideoGridAdapter() {
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
RecyclerView.ViewHolder viewHolder;
context = parent.getContext();
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_row, parent, false);
// set the view's size, margins, paddings and layout parameters
viewHolder = new VideoViewHolder(v);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
VideoViewHolder videoHolder = (VideoViewHolder) holder;
if (VideoGridActivity.listOfVideos.get(position).isPlaying()) {
//Playing Video :- Show VideoView and make play button GONE
((VideoViewHolder) holder).getVideoView().setVisibility(View.VISIBLE);
((VideoViewHolder) holder).getPlayButton().setVisibility(View.GONE);
//Play Video in video View
((VideoViewHolder) holder).getVideoView().setVisibility(View.VISIBLE);
((VideoViewHolder) holder).getVideoView().setVideoURI(Uri.parse(VideoGridActivity.listOfVideos.get(position).getVideoURL()));
// MediaControlandroid.widget.VideoView videoView = (VideoView) headerView.findViewById(R.id.vdo_banner);ler md = new MediaController(getActivity());
((VideoViewHolder) holder).getVideoView().setMediaController(null);
((VideoViewHolder) holder).getVideoView().requestFocus();
// videoView.setZOrderOnTop(true);
((VideoViewHolder) holder).getVideoView().start();
((VideoViewHolder) holder).getVideoView().setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return true;
}
});
((VideoViewHolder) holder).getVideoView().setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.setLooping(true);
}
});
} else {
//Not playing make videoview gone and show play button
((VideoViewHolder) holder).getVideoView().setVisibility(View.GONE);
((VideoViewHolder) holder).getPlayButton().setVisibility(View.VISIBLE);
}
//set thumbnail image using video url
Picasso.with(context)
.load(VideoGridActivity.listOfVideos.get(position).getImageURL()).fit().placeholder(VideoGridActivity.listOfVideos.get(position).getImageURLTest())
.networkPolicy(NetworkPolicy.OFFLINE).fit()
.centerCrop()
.into(((VideoViewHolder) holder).getVideoThumb(), new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError() {
// Try again online if cache failed
Picasso.with(context)
.load(VideoGridActivity.listOfVideos.get(position).getImageURL()).fit().placeholder(VideoGridActivity.listOfVideos.get(position).getImageURLTest())
.centerCrop()
.into(((VideoViewHolder) holder).getVideoThumb());
}
});
((VideoViewHolder) holder).getContainer().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onCardClickListner.OnCardClicked(v, position);
}
});
}
@Override
public int getItemCount() {
return VideoGridActivity.listOfVideos.size();
}
public void setOnCardClickListner(OnCardClickListner onCardClickListner) {
this.onCardClickListner = onCardClickListner;
}
public interface OnCardClickListner {
void OnCardClicked(View view, int position);
}
}
布局活动主要
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ui.activity.VideoGridActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/video_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:foregroundGravity="center"
app:layout_behavior="@string/appbar_scrolling_view_behavior"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_dialer" />
</android.support.design.widget.CoordinatorLayout>
Recyclerview项目
Recyclerview item
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="5dp">
<ImageView
android:id="@+id/video_thumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:visibility="gone" />
<!--Add a mask over video thumbnail with a play button icon-->
<RelativeLayout
android:id="@+id/play_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#68472986">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:src="@android:drawable/ic_media_play" />
</RelativeLayout>
</FrameLayout>
这篇关于水平ScrollView内有多个YouTubePlayerFragments-所有播放器都显示最后加载的视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!