Horizo​​ntal ScrollView 中的多个 YouTubePlayerFragments - 所有播放器都显示最后加载的视频

Multiple YouTubePlayerFragments inside a Horizontal ScrollView - all the players display the last loaded video

我想在 Horizo​​ntal ScrollView 中显示 多个 YouTube 视频。为此,我正在动态添加 YouTubePlayerFragments。这是我的代码片段:

 //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 播放器。下面是视频的加载方式。

显示所有玩家最后加载的视频。我调试了 - 它用第一个视频初始化所有播放器,然后用第二个视频初始化所有播放器等等,直到最后一个。

The issue is already discussed here. 似乎可以解决在我的 VideoFragment 中初始化 "setUserVisibleHint(boolean isVisibleToUser)" 内的播放器而不是 OnResume(),但我不知道如何将其与我的 Horizo​​ntalScrollView

有没有办法在水平滚动视图中加载多个 YouTube 视频?

我们将不胜感激!

我认为不可能创建 YouTube Player Fragment 的多个实例,因为它是 Singleton

无论你创建了多少个实例,它们都是一样的,你的水平滚动视图将显示你添加的最后一个 VideoFragment 的缩略图。

或者,您可以通过显示视频拇指并点击拇指在 youtube 播放器的帮助下播放视频产生多个 YouTube 片段的错觉

      // 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 的视图容器中添加 youtube 片段,并开始使用视频 ID 播放视频

videoThumbImageView.setOnClickListenr(..)
{...

 //Add Youtube fragment in container and start playing video
}

这只是一个伪代码,但你明白了。

编辑

添加了有关如何通过点击缩略图播放和停止视频的代码。

我离线所以无法使用 YouTube 片段所以我使用 Videoview 播放随机视频你可以用 YouTube 片段替换 videoview 和。保证它仍然很好用

保存视频列表的数组列表

    public static ArrayList<VideoModel> listOfVideos = new ArrayList<>();

跟踪当前播放视频的变量

      // Allows to remember the last item shown on screen
        private int lastPosition = 0;

Recycler 查看项目点击监听器

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

视频模型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);
    }

}

布局activity主要

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

回收站查看项目

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