我正在尝试在YouTubePlayerSupportFragment
项目中使用ListView
。 ListView
位于Fragment
内的Activity
内。由于存在嵌套片段,我使用getChildFragmentManager()
方法尝试从XML布局中查找片段。这是代码。
爪哇
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>
问题在于,当我尝试通过执行findFragmentById()
从XML获取它来创建片段时,它返回null,这就是发布到堆栈跟踪的内容。
我正在尝试关注YouTube API示例并对嵌套片段进行更改,但我无法找出导致问题的原因。
答案 0 :(得分:3)
您采取的整个方法都存在问题。
首先,直接从XML中扩展子片段是not supported。嵌套片段时,必须使用父片段中的getChildFragmentManager
以语音方式添加片段。
其次,即使它起作用(在某些情况下也可能),你已经夸大了视图但没有将它添加到实际片段的布局中。这就是inflate
方法中的second and third parameters所针对的内容。 FragmentManager
将在其当前布局中查找片段,或在backstack中查找事件,但无法找到以随机XML格式膨胀的片段,并且永远不会投入使用。
最后,也是最重要的一点,你永远不应该在ListView
中添加片段作为项目。片段期望生命周期与其所处的活动相关联,而ListView
或任何AdapterView
通常会根据需要创建,销毁和回收其子项。
可能的解决方案:
您的列表中需要多少个视频?如果它们不多,ScrollView + LinearLayout实际上可能是最简单的解决方案。
如果你真的需要View回收,也许你可以在每一行都没有实时视频吗?请考虑在您的行中使用YouTubeThumbnailView,然后将您的用户重定向到另一个活动/将视频加载到位于布局列表外部的单个YoutubeFragment
中。
如果您肯定希望直接在列表中的每一行播放视频,则需要在行布局上使用YoutubePlayerView而不是片段。在这种情况下,请仔细阅读文档,因为您需要自己处理视频初始化和查看回收。
答案 1 :(得分:1)
您的应用会崩溃当您尝试使用Fragment
每个ListView
项目对视图进行充气时(因为片段ID中的重复,例如此quiz)
有两个解决方案(其中一个来自@ivagarz回答):
1-您只能显示一个YouTube视频使用YouTubePlayerView
上方的ListView
进入Activity
布局但您的Activity
必须延伸YouTubeBaseActivity
赞{{ 3}}(我认为这个解决方案无法帮助您解决问题)
2-您可以使用YouTubeThumbnailView
将youtube缩略图将每个项目的视频图像显示为ListView
,并使用YouTube上的youtube播放器按钮缩略图图像用于显示视频。
赞下一张图片:
用户点击youtube播放器按钮时,您有两种方法:
使用YouTubePlayerSupportFragment
的 第一个选项:您可以将YouTubeThumbnailView
替换为YouTubePlayerSupportFragment
如果您选择此选项,您必须:
A-以编程方式添加YouTubePlayerSupportFragment
(以避免Fragment
ID中的重复。)
B-仅在ListView
为YouTube Android Player API Doc时显示一个视频。
前:
list_item.xml
项的 ListView
布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parent_relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.google.android.youtube.player.YouTubeThumbnailView
android:id="@+id/youtube_thumbnail"
android:layout_width="fill_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"
android:visibility="gone"/>
<RelativeLayout android:id="@+id/relativeLayout_over_youtube_thumbnail"
android:layout_width="fill_parent"
android:layout_height="250dp"
android:background="@color/color_background_transparent"
android:visibility="gone">
<ImageView android:id="@+id/btnYoutube_player"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/youtube_player"/>
</RelativeLayout>
</RelativeLayout>
在getView
适配器的ListView
mehtod:
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflator.inflate(R.layout.list_item.xml, parent, false);
final RelativeLayout relativeLayoutOverYouTubeThumbnailView = (RelativeLayout) convertView.findViewById(R.id.relativeLayout_over_youtube_thumbnail);
final YouTubeThumbnailView youTubeThumbnailView = (YouTubeThumbnailView) convertView.findViewById(R.id.youtube_thumbnail);
// get parent relative layout
RelativeLayout parentRelativeLayout = (RelativeLayout) convertView.findViewById(R.id.parent_relativeLayout);
// then create dynamic FrameLayout
FrameLayout.LayoutParams dynamicFrameLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
final FrameLayout dynamicFrameLayout = new FrameLayout(ctx);
dynamicFrameLayout.setId(Different_ID);
dynamicFrameLayout.setLayoutParams(dynamicFrameLayoutParams);
// then add dynamic FrameLayout as children in parent relative layout
parentRelativeLayout.addView(dynamicFrameLayout);
ImageView youtubePlayerButton = (ImageView) convertView.findViewById(R.id.btnYoutube_player);
youtubePlayerButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
View parentView = (View) v.getParent().getParent();
YouTubeThumbnailView youTubeThumbnailView = (YouTubeThumbnailView) parentView.findViewById(R.id.youtube_thumbnail);
RelativeLayout relativeLayoutOverYouTubeThumbnailView = (RelativeLayout) parentView.findViewById(R.id.relativeLayout_over_youtube_thumbnail);
youTubeThumbnailView.setVisibility(View.GONE);
relativeLayoutOverYouTubeThumbnailView.setVisibility(View.GONE);
YouTubeFragment youTubeFragment = new YouTubeFragment();
youTubeFragment.youTubeFragmentInitialize(VideoID, youTubeFragment, parentView);
getSupportFragmentManager()
.beginTransaction()
.replace(dynamicFrameLayout.getId(), youTubeFragment)
.commit();
}
});
final YouTubeThumbnailLoader.OnThumbnailLoadedListener onThumbnailLoadedListener = new YouTubeThumbnailLoader.OnThumbnailLoadedListener(){
@Override
public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
}
@Override
public void onThumbnailLoaded(YouTubeThumbnailView youTubeThumbnailView, String s) {
loadingImage.setVisibility(View.GONE);
youTubeThumbnailView.setVisibility(View.VISIBLE);
relativeLayoutOverYouTubeThumbnailView.setVisibility(View.VISIBLE);
}
};
youTubeThumbnailView.initialize(API_KEY, new YouTubeThumbnailView.OnInitializedListener() {
@Override
public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) {
youTubeThumbnailLoader.setVideo(VideoID);
youTubeThumbnailLoader.setOnThumbnailLoadedListener(onThumbnailLoadedListener);
}
@Override
public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
}
});
}
我创建了自己的Fragment
,来自YouTubePlayerSupportFragment
:
public class YouTubeFragment extends YouTubePlayerSupportFragment {
public void youTubeFragmentInitialize(final String videoId, final YouTubeFragment fragment, final View parent) {
fragment.initialize(apiKey, new YouTubePlayer.OnInitializedListener() {
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, final YouTubePlayer youTubePlayer, boolean wasRestored) {
youTubePlayer.setShowFullscreenButton(false);
if (!wasRestored) {
youTubePlayer.loadVideo(videoId);
}
}
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
Log.e("app", youTubeInitializationResult.toString());
}
});
}
}
第二次选项使用YouTubeStandalonePlayer
或创建自己的Activity
扩展YouTubeBaseActivity
:当用户点击youtube播放器按钮时,您可以创建一个Intent来打开显示视频的新活动
Intent intent = YouTubeStandalonePlayer.createVideoIntent(context, YOUR_DEVELOPER_KEY, VIDEO_ID);
startActivity(intent);