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();
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
Is there a way I can load multiple YouTube videos in a Horizontal ScrollView?
Any sort of help will be appreciated!
I dont think it is possible to create multiple instance of YouTube Player Fragment as it is Singleton
.
No matter how many instances you make they all gone be same and your horizontal scrollview will show thumbnail of last VideoFragment you added .
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);
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.
Edit
Added code for how to play and stop videos on tap of thumbnails.
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 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 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;
}
}
Adpter itself
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);
}
}
Layout activity main
<?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 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>