如何在另一个片段中使用 YouTubePlayerFragment 加载 YouTubePlayer? (安卓)
Posted
技术标签:
【中文标题】如何在另一个片段中使用 YouTubePlayerFragment 加载 YouTubePlayer? (安卓)【英文标题】:How to load YouTubePlayer using YouTubePlayerFragment inside another Fragment?? (Android) 【发布时间】:2013-11-19 19:38:52 【问题描述】:我想使用 API 中的 YouTubePlayerFragment 在片段中加载 YoutubePlayer
我的片段的.xml文件是:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_>
<!-- VIDEO CONTENT -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_
android:layout_weight="1"
android:paddingLeft="@dimen/layout_horizontal_margin"
android:paddingRight="@dimen/layout_horizontal_margin"
android:paddingTop="@dimen/layout_vertical_margin"
android:paddingBottom="@dimen/layout_vertical_margin" >
<fragment
android:name="com.google.android.youtube.player.YouTubePlayerFragment"
android:id="@+id/youtubeplayer_fragment"
android:layout_
android:layout_/>
</LinearLayout>
<!-- LYRIC CONTENT -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_
android:layout_weight="2" >
<LinearLayout
android:orientation="vertical"
android:layout_
android:layout_
android:background="@drawable/af_background"
android:layout_centerInParent="true" />
<!-- TEXT STRUCTURE -->
<LinearLayout
android:orientation="vertical"
android:id="@+id/lyric_content"
android:layout_
android:layout_
android:layout_centerHorizontal="true" >
<LinearLayout
android:id="@+id/start_layout"
android:orientation="vertical"
android:layout_
android:layout_
android:gravity="center"
android:layout_gravity="center_horizontal"
android:layout_centerInParent="true">
<TextView
android:id="@+id/text_view"
android:layout_
android:layout_
android:layout_marginTop="@dimen/lyric_margin_top"
android:gravity="center"
android:text="@string/textTitle2"
android:textSize="@dimen/lyric_size"
android:textIsSelectable="false"/>
</LinearLayout>
</LinearLayout>
<!-- FRONT BACKGROUND -->
<ImageView
android:id="@+id/high_part_image"
android:layout_
android:layout_
android:layout_alignParentTop="true"
android:src="@drawable/af_background_up_side"
android:scaleType="fitStart"/>
<ImageView
android:id="@+id/low_part_image"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:src="@drawable/af_background_down_side"
android:scaleType="fitEnd"/>
</RelativeLayout>
</LinearLayout>
如您所见,我添加了一个
现在加载这个 .xml 的 Fragment 是:
public class MyFragment extends Fragment
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_ITEM_ID = "item_id";
/**
* The content this fragment is presenting.
*/
private Items.ItemList mItem;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public MyFragment()
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID))
// Load the content specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load content from a content provider.
mItem = Items.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(android.R.layout.titles_fragment, container, false);
// Show the content as text in a TextView.
if (mItem != null)
((TextView) rootView.findViewById(android.R.id.textTitle2)).setMovementMethod(new ScrollingMovementMethod());
return rootView;
最后我有一个 ActivityFragment 实现了“YouTubePlayer.OnInitializedListener”并从中获取片段。
public class ItemDetailActivity extends FragmentActivity implements YouTubePlayer.OnInitializedListener
private TextView mTextView;
private ImageView hImageView;
private ImageView lImageView;
public static final String API_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
public static final String VIDEO_ID = "BJVlU7d-4x0";
private YouTubePlayer youTubePlayer;
private YouTubePlayerFragment youTubePlayerFragment;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
if (savedInstanceState == null)
// Create the detail fragment and add it to the activity
// using a fragment transaction.
fragmentTransaction(getIntent().getStringExtra(ItemDetailFragment.ARG_ITEM_ID));
@Override
public boolean onOptionsItemSelected(MenuItem item)
switch (item.getItemId())
case android.R.id.home:
NavUtils.navigateUpTo(this, new Intent(this, ItemListActivity.class));
return true;
return super.onOptionsItemSelected(item);
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider,
YouTubeInitializationResult result)
Toast.makeText(this,
"YouTubePlayer.onInitializationFailure(): " + result.toString(),
Toast.LENGTH_LONG).show();
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player,
boolean wasRestored)
Toast.makeText(getApplicationContext(),
"YouTubePlayer.onInitializationSuccess()",
Toast.LENGTH_LONG).show();
if (!wasRestored)
player.cueVideo(VIDEO_ID);
private void fragmentTransaction(String id)
Bundle arguments = new Bundle();
Fragment fragment;
String content = Items.ITEM_MAP.get(id).content;
if(content.equalsIgnoreCase("Title 1"))
// Fragment transaction
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);
fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
if(content.equalsIgnoreCase("Title 2"))
// Fragment transaction
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);
fragment = new MyFragment);
fragment.setArguments(arguments);
FragmentManager fm = getSupportFragmentManager();
//youTubePlayerFragment = fragment.getChildFragmentManager().findFragmentById(R.id.youtubeplayer_fragment);
//youTubePlayerFragment = (YouTubePlayerFragment)getFragmentManager().findFragmentById(R.id.youtubeplayer_fragment);
//Fragment ytbfragment = fragment.getChildFragmentManager().findFragmentById(R.id.youtubeplayer_fragment);
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.item_detail_container, fragment);
//ft.add(R.id.youtubeplayer_fragment, youTubePlayerFragment);
ft.commit();
//youTubePlayerFragment.initialize(API_KEY, this);
if(content.equalsIgnoreCase("Title 3"))
// Fragment transaction
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);
fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
在标题 2 中是我获取片段的地方,也是我尝试使用不同方法获取 youtube 播放器内部片段的地方,但它不起作用。 当我尝试获取 YoutubeFragment 时,总是会崩溃加载 .xml 以获取播放器表单。
如果我只加载原始片段,应用程序会很好地获取 xml 文件。
有什么问题?
【问题讨论】:
点击这个链接,它会帮助你[链接][1] [1]:***.com/questions/18664934/… 【参考方案1】:我已经研究这个问题好几天了,我终于找到了解决方案。我把代码贴在这里好吗?
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View fragmentYoutubeView = inflater.inflate(R.layout.fragment_youtube, container, false);
mYoutubePlayerFragment = new YouTubePlayerSupportFragment();
mYoutubePlayerFragment.initialize(youtubeKey, this);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_youtube_player, mYoutubePlayerFragment);
fragmentTransaction.commit();
mYoutubeVideoTitle = (TextView)fragmentYoutubeView.findViewById(R.id.fragment_youtube_title);
mYoutubeVideoDescription = (TextView)fragmentYoutubeView.findViewById(R.id.fragment_youtube_description);
mYoutubeVideoTitle.setText(getArguments().getString(Resources.KEY_VIDEO_TITLE));
mYoutubeVideoDescription.setText(getArguments().getString(Resources.KEY_VIDEO_DESC));
VideoFragment.setTextToShare(getArguments().getString(Resources.KEY_VIDEO_URL));
return fragmentYoutubeView;
在这段代码中,我通过一个 Intent 传递 youtube 视频 ID (url)、标题和描述,并将它们放入 textViews。要播放 youtubePlayerFragment,我使用 frameLayout (fragment_youtube_player),如下所示:
<FrameLayout
android:id="@+id/fragment_youtube_player"
android:layout_
android:layout_
android:layout_weight="1"/>
我将权重设为 1,因为包含 Frame 和 textViews 的 LinearLayout 的权重为 3,以强制视图占据我告诉它们的空间。
问题的工具包在这里:
mYoutubePlayerFragment = new YouTubePlayerSupportFragment();
mYoutubePlayerFragment.initialize(youtubeKey, this);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_youtube_player, mYoutubePlayerFragment);
fragmentTransaction.commit();
此代码以编程方式将 FrameLayout 替换为 youtubePlayerSupportFragment。所有这些都在一个 Android 片段中,并且可以正常工作。
编辑 1:
我看到一些关于 Fragment 如何管理 Youtube API 的初始化成功和失败的困惑。为了澄清我的片段标题如下所示:
public class FragmentYoutubePlayerGenerator extends Fragment
implements YouTubePlayer.OnInitializedListener
而且这两种方法的实现都很简单:
@Override
public void onInitializationSuccess(Provider provider,
YouTubePlayer player,
boolean wasRestored)
if(!wasRestored)
player.cueVideo(mVideoInfo.getId());
@Override
public void onInitializationFailure(Provider provider,
YouTubeInitializationResult result)
if (result.isUserRecoverableError())
result.getErrorDialog(this.getActivity(),1).show();
else
Toast.makeText(this.getActivity(),
"YouTubePlayer.onInitializationFailure(): " + result.toString(),
Toast.LENGTH_LONG).show();
我让开发人员选择是否在错误处理中留下 result.toString(),一些用户不喜欢在他们的屏幕上看到很多他们不理解的数字,但它也很好他们是因为他们可以对其进行快照并将其发送给您以调试错误。
【讨论】:
您能否用完整的代码更新您的答案,显示哪些片段应该扩展 YouTubeABasectivity,哪些不应该以及您如何称呼它们。请更新它。我也面临着类似的问题。 是否可以不扩展Activity? @iDroidExplorer 你不能用 Fragment 扩展 YoutubeABaseActivity,你只需要 IMPLEMENT YouTubePlayer.OnInitializedListener,我会更新代码 这是我在这个问题上看到的最好的答案!谢谢! “mYoutubePlayerFragment”的类型是什么?我试过你的方法,它抱怨这一行:fragmentTransaction.replace(R.id.fragment_youtube_player, mYoutubePlayerFragment), mYoutubePlayerFragment is not fragment.以上是关于如何在另一个片段中使用 YouTubePlayerFragment 加载 YouTubePlayer? (安卓)的主要内容,如果未能解决你的问题,请参考以下文章