7

I want to set YouTube videos within ViewPager. For this I have set FrameLayout in adapter and I have set YoutubeVideoFragment in it like below:

My Adapter for ViewPager:

import android.app.Activity;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

import np.com.test.R;
import np.com.test.fragment.YoutubeVideoFragment;

/**
 * Created by Vikash on 8/18/2015.
 */
public class TutorialVideoAdapter extends PagerAdapter {
private List<String> mList;
private Activity mActivity;

public TutorialVideoAdapter(Activity activity, List<String> list) {
    mActivity = activity;
    mList = list;
}

@Override
public int getCount() {
    return mList.size();
}

@Override
public boolean isViewFromObject(View view, Object object) {
    return view == object;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {

    LayoutInflater inflater = (LayoutInflater) mActivity
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.pager_video_tutorial, container, false);

    YoutubeVideoFragment fragment = new YoutubeVideoFragment();
    Bundle bundle = new Bundle();
    bundle.putString("video_key", mList.get(position));
    fragment.setArguments(bundle);

    FragmentTransaction transaction = mActivity.getFragmentManager().beginTransaction();
    transaction.add(R.id.fragment_container, fragment);
    transaction.commit();

    container.addView(view);
    return view;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((View) object);
}
}

In above adapter in which YoutubeVideoFragment is use to load Youtube video.

YoutubeVideoFragment:

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerFragment;

import np.com.test.R;
import np.com.test.utils.Config;

/**
 * Created by Vikash on 8/18/2015.
 */
public class YoutubeVideoFragment extends Fragment implements YouTubePlayer.OnInitializedListener {

    private String YOUTUBE_VIDEO_CODE;
    private static final int RECOVERY_DIALOG_REQUEST = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        YOUTUBE_VIDEO_CODE = getArguments().getString("video_key");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View fragmentYoutubeView = inflater.inflate(R.layout.fragment_youtube_video, container, false);
        YouTubePlayerFragment mYoutubePlayerFragment = new YouTubePlayerFragment();
        mYoutubePlayerFragment.initialize(Config.GOOGLE_API_KEY, this);

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_youtube_player, mYoutubePlayerFragment);
        fragmentTransaction.commit();

        return fragmentYoutubeView;
    }

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
        if (!wasRestored) {
            player.cueVideo(YOUTUBE_VIDEO_CODE);
        }
    }

    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
        if (errorReason.isUserRecoverableError()) {
            errorReason.getErrorDialog(getActivity(), RECOVERY_DIALOG_REQUEST).show();
        } else {
            String errorMessage = String.format(
                    getString(R.string.error_player), errorReason.toString());
            Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show();
        }
    }
}

XML layout code for both fragmenet_youtube_videoandpager_video_tutorial:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_youtube_player"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

What i got? Only showing first position fragment. I can see only one video in viewpager remaining page are are blank.

What i tried? I tried to search for the solution from yesterday in Google but couldn't get success.

My Problem: How to load remaining YoutubeVideoFragment?

Thank you.

salih kallai
  • 879
  • 2
  • 13
  • 34
Viks
  • 1,510
  • 4
  • 22
  • 50

3 Answers3

7

I got the error that the YouTube view is overlayed by my view pager when the pager contains multiple YouTubePlayerFragments.

After a lot of research, I solved it as follows.

  • Override setUserVisibleHint() of the fragment.

  • Release the previous YouTubePlayer (mYoutubePlayer).

  • Create a new instance of the player by initialize().

  • In onInitilizationSuccess, load the player with the youtube_video_id.

Note: I am using FragmentStatePagerAdapter.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (!isVisibleToUser && mYoutubePlayer != null) {
        mYoutubePlayer.release();
    }
    if (isVisibleToUser && mYouTubePlayerSupportFragment != null) {
        mYouTubePlayerSupportFragment.initialize(API_KEY, Context);
    }
Pang
  • 9,564
  • 146
  • 81
  • 122
Ram Prakash Bhat
  • 1,308
  • 12
  • 21
  • hi @Ram I am doing the same everything is working very fine except when i scroll very fast view pager 5 to 6 times then again this issue is coming. can you please explain why? – Jishant Dec 28 '17 at 09:57
7

Inspired by the answer above, I have a working solution for this problem.

In OnCreate():

mYouTubePlayerSupportFragment = YouTubePlayerSupportFragment.newInstance();
    if (getUserVisibleHint()) {
        Log.v (TAG, "Committing transaction, URL : " + getArguments().getString(KeyConstant.KEY_VIDEO_URL));
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.replace(R.id.fl_youtube_player, mYouTubePlayerSupportFragment).commit();
        mYouTubePlayerSupportFragment.initialize(DeveloperKey.DEVELOPER_KEY, this);
    }

In setUserVisibleHint():

if (!isVisibleToUser && mYoutubePlayer != null) {
    Log.v (TAG, "Releasing youtube player, URL : " + getArguments().getString(KeyConstant.KEY_VIDEO_URL));
    mYoutubePlayer.release();
    FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
    transaction.remove(mYouTubePlayerSupportFragment).commit();
}
if (isVisibleToUser && mYouTubePlayerSupportFragment != null) {
    Log.v (TAG, "Initializing youtube player, URL : " + getArguments().getString(KeyConstant.KEY_VIDEO_URL));
    FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
    transaction.replace(R.id.fl_youtube_player, mYouTubePlayerSupportFragment).commit();
    mYouTubePlayerSupportFragment.initialize(DeveloperKey.DEVELOPER_KEY, this);
}
Pang
  • 9,564
  • 146
  • 81
  • 122
gaurav jain
  • 3,119
  • 3
  • 31
  • 48
  • if anyone is getting `IllegalStateException:` then use `commitAllowingStateLoss();` The code snipped is `transaction.remove(mYouTubePlayerSupportFragment).commitAllowingStateLoss();` . Add this for condition `if (!isVisibleToUser && mYoutubePlayer != null)` – AkshayT Mar 24 '18 at 14:45
  • Can you please provide complete code or any link of the same? – Astha Garg Feb 18 '20 at 07:16
-1
public class PlayerFragment extends Fragment implements YouTubePlayer.OnInitializedListener{

    YouTubePlayer player;
    Context context;
    YouTubePlayerSupportFragment youTubePlayerSupportFragment;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getActivity();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_layout,container,false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        youTubePlayerSupportFragment = new YouTubePlayerSupportFragment();
        getChildFragmentManager().beginTransaction().replace(R.id.container,youTubePlayerSupportFragment).commit();

    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (!isVisibleToUser && player != null) {
            player.release();
        }
        if (isVisibleToUser && youTubePlayerSupportFragment != null) {
            youTubePlayerSupportFragment.initialize(YOUR_KEY, this);
        }
    }

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
        this.player = youTubePlayer;
        this.player.loadVideo("BqVoYfFrCMs");

        this.player.play();
    }

    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {

    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
  • 1
    Code only answers are generally frowned upon in the stack overflow community. Please add a description of what was wrong and/or what you fixed in order to solve the problem – Cody Guldner May 27 '17 at 06:26