2013-04-04 41 views
5

我试图在ListView项目中使用YouTubePlayerSupportFragmentListView位于ActivityFragment之内。由于存在嵌套片段,我使用getChildFragmentManager()方法尝试从XML布局中查找片段。这是代码。ListView项目中的YouTubePlayerSupportFragment为空

的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> 

的问题是,当我尝试做findFragmentById()从XML得到它来创建片段,它返回null,和这就是发布到堆栈跟踪的内容。

我正试图按照YouTube API示例进行嵌套片段所需的更改,但找不到导致此问题的原因。

+0

你能共享此命令的输出'adb shell dumpsys activity '?它包含活动和添加的片段列表。 – 2014-08-24 11:22:14

+0

你使用支持库碎片吗? – Yuraj 2014-08-25 21:04:50

+0

是的。我有支持库碎片。 – 2014-08-26 02:40:10

回答

3

整个方法都有问题。

首先,直接从XML扩充子片段是not supported。在嵌套片段时,您必须在父片段中使用getChildFragmentManager以二进制方式添加它们。

其次,即使它工作(并且在某些情况下可能),您已经夸大了视图但没有将其添加到实际的片段布局。这就是inflate方法中的second and third parametersFragmentManager将在其当前布局或事件中查找片段,但无法找到以随机XML形式膨胀并永不投入使用的片段。

最后,也是最重要的,你不应该在ListView中添加片段作为项目。碎片的生命周期与他们所处的活动有关,而一般情况下,ListView或任何其他AdapterView都会根据需要创建,销毁和回收其子项。

可能的解决方案:

  • 多少视频,你需要你的名单上?如果它们不是很多,那么ScrollView + LinearLayout实际上可能是最简单的解决方案。

  • 如果你真的需要查看回收,也许你可以在每一行都没有实时视频?考虑在您的行中使用YouTubeThumbnailView,然后将用户重定向到另一个活动,或者在位于布局列表外部的单个YoutubeFragment中加载视频。

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

+0

我曾尝试使用YouTubePlayerView里面的ListView,但有问题发生初始化为每个行。然后,我也尝试了使用YouTubePlayerSupportFragment的listview,但是当队列视频将位置更改为加载的视频时也是如此。它不在每一行中加载。你可以分享每一行直播视频播放的任何例子。 – 2016-08-16 11:09:16

1

您的应用程序会崩溃当您尝试与同一FragmentListView项膨胀视图(如重复的片段ID这样quiz

有两种解决方案(其中从@ivagarz答案之一):

1可以只显示一个YouTube视频使用YouTubePlayerViewListView以上到您的Activity布局,但你Activity必由之路延伸YouTubeBaseActivityYouTube Android Player API Doc(我认为此解决方案将不会帮助您解决您的问题)

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

下一张图片:

enter image description here

当YouTube播放器按钮用户点击,有两种方式:

首先使用YouTubePlayerSupportFragment选项:您可以更换YouTubeThumbnailViewYouTubePlayerSupportFragment 如果您选择此选项,您必须:

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

B-只显示一个视频到你的ListView作为answer of this Question

防爆

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> 

getViewListView适配器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) { 

      } 
     }); 
} 

我创建了自己的FragmentYouTubePlayerSupportFragment延伸:

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); 
+0

真棒+100,你对第1点很好的解释 – 2017-10-16 06:00:34