Как загрузить YouTubePlayer с помощью YouTubePlayerFragment внутри другого фрагмента? (Android)

Я хочу загрузить YoutubePlayer в фрагмент, используя YouTubePlayerFragment из API

Файл .xml моего фрагмента:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- VIDEO CONTENT --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="0dp" 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_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <!-- LYRIC CONTENT --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" > <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="@drawable/af_background" android:layout_centerInParent="true" /> <!-- TEXT STRUCTURE --> <LinearLayout android:orientation="vertical" android:id="@+id/lyric_content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" > <LinearLayout android:id="@+id/start_layout" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center_horizontal" android:layout_centerInParent="true"> <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="match_parent" 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_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:src="@drawable/af_background_up_side" android:scaleType="fitStart"/> <ImageView android:id="@+id/low_part_image" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:src="@drawable/af_background_down_side" android:scaleType="fitEnd"/> </RelativeLayout> </LinearLayout> 

Как вы можете видеть, я добавил

Теперь Фрагмент, который загружает этот .xml, это:

 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 (eg 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 с помощью разных методов, но он не работает. Всегда загружайте файл .xml, пытаясь получить форму игрока, когда я пытаюсь получить YoutubeFragment.

Если я загружаю только оригинальный фрагмент, приложение получает XML-файл.

В чем проблема?

Solutions Collecting From Web of "Как загрузить YouTubePlayer с помощью YouTubePlayerFragment внутри другого фрагмента? (Android)"

Я работаю над этой проблемой уже несколько дней, и я наконец нашел решение. Я отправлю код здесь нормально?

 @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 (url), название и описание и поместите их в текстовые элементы. Чтобы воспроизвести файл youtubePlayerFragment, я использую frameLayout (fragment_youtube_player) следующим образом:

 <FrameLayout android:id="@+id/fragment_youtube_player" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1"/> 

Я положил вес 1, потому что LinearLayout, содержащий Frame и textViews, имеет вес 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, и оно работает.

EDIT 1:

Я видел некоторую путаницу в том, как Fragment управляет успехом инициализации и неудачей API Youtube. Чтобы прояснить заголовок Fragment выглядит следующим образом:

 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 () в обработке ошибок, некоторым пользователям не понравится видеть много номеров, которые они не понимают на своих экранах, но также полезно их размещать, потому что они Может сделать снимок и отправить их вам для отладки ошибки.