5

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

4

2 回答 2

3

您采取的整个方法存在问题。

首先,不支持直接从 XML 扩充子片段。嵌套片段时,您必须getChildFragmentManager在父片段中动态添加它们。

其次,即使它有效(并且在某些情况下可能),您已经膨胀了视图但没有将其添加到实际片段的布局中。这就是方法中的第二个和第三个参数inflate用途。将FragmentManager在其当前布局中查找片段,或在后台堆栈中查找事件,但找不到在随机 XML 中膨胀且从未投入使用的片段。

最后,也是最重要的一点,你永远不应该将片段作为项目添加到ListView. Fragment 期望有一个与它们所在的 Activity 相关联的生命周期,而 aListView或任何AdapterView一般的,将根据需要创建、销毁和回收其子级。

可能的解决方案:

  • 您的列表中需要多少视频?如果它们的数量不多,则 ScrollView+LinearLayout 实际上可能是最简单的解决方案。

  • 如果你真的需要 View 回收,也许你可以不用每一行的直播视频?考虑在您的行中使用YouTubeThumbnailViewYoutubeFragment ,然后将您的用户重定向到另一个活动/将视频加载到位于布局列表之外的单个活动中。

  • 如果您确实希望直接在列表中的每一行上播放视频,则需要在行布局上使用YoutubePlayerView而不是片段。在这种情况下,请仔细阅读文档,因为您需要自己处理视频初始化和查看回收。

于 2014-08-29T08:29:24.897 回答
1

当您尝试使用相同的Fragment每个ListView项目来扩展视图时,您的应用程序将崩溃(作为片段 id 中的重复,如本测验

有两个解决方案(其中一个来自@ivagarz答案):

1-您只能显示一个 youtube 视频YouTubePlayerViewListView您的Activity布局中使用但您Activity必须YouTubeBaseActivityYouTube Android Player API Doc一样扩展(我认为此解决方案不会帮助您解决问题)

2-您可以使用youtube 播放器按钮在用于显示视频的 youtube 缩略图上显示YouTubeThumbnailView每个项目的视频的youtube 缩略图图像。ListView

喜欢下一张图片:

在此处输入图像描述

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

第一个选项使用YouTubePlayerSupportFragment:您可以替换YouTubeThumbnailViewYouTubePlayerSupportFragment 如果您选择此选项,您必须:

A-YouTubePlayerSupportFragment以编程方式即时添加(以避免在FragmentId 中重复)。

ListViewB- 仅在此问题的答案中显示一个视频。

例如

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

  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); 
于 2015-04-20T20:52:42.053 回答