ListView项目中的YouTubePlayerSupportFragment为null

时间:2013-04-04 04:39:12

标签: android android-fragments youtube-api

我正在尝试在YouTubePlayerSupportFragment项目中使用ListViewListView位于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示例并对嵌套片段进行更改,但我无法找出导致问题的原因。

2 个答案:

答案 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播放器按钮缩略图图像用于显示视频。

下一张图片:

enter image description here

用户点击youtube播放器按钮时,您有两种方法:

使用YouTubePlayerSupportFragment

第一个选项:您可以将YouTubeThumbnailView替换为YouTubePlayerSupportFragment 如果您选择此选项,您必须:

A-以编程方式添加YouTubePlayerSupportFragment(以避免Fragment ID中的重复。)

B-仅在ListViewYouTube 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);