android - 如何在另一个 fragment 中使用 YouTubePlayerFragment 加载 YouTubePlayer? (安卓)

标签 android android-fragments youtube-api android-youtube-api

我想使用 API 中的 YouTubePlayerFragment 在 fragment 中加载 YoutubePlayer

我的 fragment 的 .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 的 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;
    }
}

最后,我有一个实现“YouTubePlayer.OnInitializedListener”的 ActivityFragment,我从中获取 fragment 。

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 中,我获得了 fragment ,并且我试图用不同的方法获取 youtube 播放器的内部 fragment ,但它不起作用。 当我尝试获取 de YoutubeFragment 时,总是崩溃加载 .xml 试图让播放器形成。

如果我只加载原始 fragment ,应用程序会很好地获取 xml 文件。

有什么问题吗?

最佳答案

几天来我一直在研究这个问题,我终于找到了解决方案。我会在这里发布代码好吗?

@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_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"/>

我将权重设置为 1,因为包含 Frame 和 textView 的 LinearLayout 的权重为 3,以强制 View 占用我指定的空间。

问题的工具包在这里:

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 fragment 中,并且可以正常工作。

编辑 1:

关于 Fragment 如何管理 Youtube API 的初始化成功和失败,我看到了一些困惑。为了阐明我的 Fragment header 如下所示:

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(),有些用户不喜欢在屏幕上看到很多他们不理解的数字,但也很好他们,因为他们可以对其进行快照并将其发送给您以调试错误。

关于android - 如何在另一个 fragment 中使用 YouTubePlayerFragment 加载 YouTubePlayer? (安卓),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19848142/

相关文章:

android - 通过 NFC 注册 Lollipop (5.1) 的自助服务终端设备

android - 使用 Picasso 从 url 添加标记

android - Android 应用程序中未调用 Facebook 登录回调

c# - 如何使用 Youtube api 查找直播视频列表?

javascript - 将视频添加到 YouTube 上用户的 "Watch Later"播放列表

youtube-api - YouTube 中的隐藏字幕作为 JSON

android - 用于了解有关 Android 应用程序设计和开发过程/方法的更多信息的资源

android - 如何在 Android Jetpack Compose 中使用字符串资源?

android - CoordinatorLayout 重叠

android - 如何动态设置FrameLayout的宽度和高度android?