I'm trying to use a YouTubePlayerSupportFragment
in a ListView
item. The ListView
is inside a Fragment
that's in an Activity
. Since there are nested fragments I'm using the getChildFragmentManager()
method to try to find the fragment from the XML layout. Here is the code.
Java
convertView = inflater.inflate(R.layout.youtube_post_layout, null);
YouTubePlayerSupportFragment youTubePlayerFragment = (YouTubePlayerSupportFragment) getChildFragmentManager().findFragmentById(R.id.youtube_video);
if (youTubePlayerFragment == null) {
Log.i("YouTube", "player is null");
} else {
Log.i("YouTube", youTubePlayerFragment.toString());
}
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<include layout="@layout/post_base_layout" />
<fragment
android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
android:id="@+id/youtube_video"
android:layout_width="match_parent"
android:layout_height="240dp"
android:layout_marginLeft="62dp"
android:layout_marginRight="32dp"
android:background="@color/light_grey"
android:cropToPadding="true"
android:padding="1dp"
android:scaleType="centerCrop" />
<include layout="@layout/post_bottom_layout" />
</LinearLayout>
The problem is that when I try to create the fragment by doing findFragmentById()
to get it from the XML, it returns null, and that's what is posted to the stack trace.
I'm trying to follow the YouTube API samples and make the changes needed for nested fragments but I can't find out what's causing the issue.
your app will crash When you try to inflate view with same
Fragment
everyListView
item (As duplication in fragment id like this quiz)There Two solution (one of them from @ivagarz answer) :
1- You can display only one youtube video Using
YouTubePlayerView
above yourListView
into yourActivity
layout But yourActivity
Must extendsYouTubeBaseActivity
Like YouTube Android Player API Doc (I Think this Solution will not help you to solve your problem)2- you can use
YouTubeThumbnailView
to Display youtube Thumbnail Image of Video for Every Item intoListView
with youtube player button over youtube Thumbnail Image Used to Display Video.Like The next Picture :
When User click on youtube player button, You Have two ways:
First option using
YouTubePlayerSupportFragment
: you can replacingYouTubeThumbnailView
withYouTubePlayerSupportFragment
If you take This Option you must :A- add
YouTubePlayerSupportFragment
programmatically on the Fly (to avoid duplication inFragment
Id).B- Display Only one Video into your
ListView
As answer of this Question.Ex:
list_item.xml
layout forListView
item:in
getView
mehtod ofListView
adapter:I was created my own
Fragment
extends fromYouTubePlayerSupportFragment
:Second option using
YouTubeStandalonePlayer
or creating your OwnActivity
extendsYouTubeBaseActivity
: Just when User click on youtube player button, you can create an Intent to open new activity to display VideoThere are problems with the whole approach you have taken.
First, inflating child fragments directly from an XML is not supported. When nesting fragments, you must add them dinamically using
getChildFragmentManager
in the parent fragment.Second, even if it worked (and it might in some cases), you have inflated the view but not added it to the actual fragment's layout. That's what the second and third parameters in the
inflate
method are there for. TheFragmentManager
will look for fragment in its current layout, or event in the backstack, but can't find fragments inflated in a random XML and never put to use.Finally, and most important, you should never add fragments as items in an
ListView
. Fragments expect to have a lifecycle tied to the Activity they are in, while aListView
, or anyAdapterView
in general, will create, destroy and recycle its children as needed.Possible solutions:
How many videos do you need on your list? If there are not many of them, a ScrollView+LinearLayout might actually be the easiest solution.
If you really need View recycling, maybe you can do without live video in every row? Consider using a YouTubeThumbnailView in your rows, then redirecting your user to another activity / loading a the video in a single
YoutubeFragment
located outside of the list on your layout.If you definitely want videos playing directly on every row in the list, you will need to use YoutubePlayerView instead of fragments on your row layout. In this case, read the documentation carefully, because you will need to handle the video initialization and view recycling yourself.