ListView 中的 YouTubePlayerFragment 出现 AppCompatActivity 错误

YouTubePlayerFragment in ListView with AppCompatActivity Error

我正在开发一个 android 应用程序。在此应用程序中,我希望在 ListViewRecyclerViewAppCompatActivity 中使用 youtube 播放器播放 youtube 视频。我已经使用了 YouTubeBaseActivity 它与此配合得很好,但我需要 AppCompatActivity。所以我使用 YouTubePlayerFragmentYouTubePlayerSupportFragment 来解决我的问题。

当我将 YouTubePlayerFragmentAppCompatActivity 一起使用时,它运行良好。但我想在 ListView 中使用它,但出现以下错误。

 android.view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class fragment
                                                                             Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
                                                                             Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f0b0063, tag null, or parent id 0x7f0b0062 with another fragment for com.google.android.youtube.player.YouTubePlayerFragment
                                                                                 at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3611)
                                                                                 at android.app.FragmentController.onCreateView(FragmentController.java:98)
                                                                                 at android.app.Activity.onCreateView(Activity.java:6182)
                                                                                 at android.support.v4.app.BaseFragmentActivityApi14.onCreateView(BaseFragmentActivityApi14.java:41)
                                                                                 at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:75)
                                                                                 at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:783)
                                                                                 at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
                                                                                 at android.view.LayoutInflater.rInflate(LayoutInflater.java:866)
                                                                                 at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:827)
                                                                                 at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
                                                                                 at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
                                                                                 at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
                                                                                 at com.example.youtubecardview.frag_youtube.custom_youtube_list_adapter.getView(custom_youtube_list_adapter.java:63)
                                                                                 at android.widget.AbsListView.obtainView(AbsListView.java:2372)
                                                                                 at android.widget.ListView.measureHeightOfChildren(ListView.java:1408)
                                                                                 at android.widget.ListView.onMeasure(ListView.java:1315)
                                                                                 at android.view.View.measure(View.java:21783)
                                                                                 at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
                                                                                 at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
                                                                                 at android.view.View.measure(View.java:21783)
                                                                                 at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
                                                                                 at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
                                                                                 at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
                                                                                 at android.view.View.measure(View.java:21783)
                                                                                 at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
                                                                                 at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:391)
                                                                                 at android.view.View.measure(View.java:21783)
                                                                                 at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
                                                                                 at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
                                                                                 at android.view.View.measure(View.java:21783)
                                                                                 at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
                                                                                 at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
                                                                                 at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
                                                                                 at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
                                                                                 at android.view.View.measure(View.java:21783)
                                                                                 at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
                                                                                 at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
                                                                                 at com.android.internal.policy.DecorView.onMeasure(DecorView.java:699)
                                                                                 at android.view.View.measure(View.java:21783)
                                                                                 at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2409)
                                                                                 at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1497)
                                                                                 at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1750)
                                                                                 at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1385)
                                                                                 at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6722)
                                                                                 at android.view.Choreographer$CallbackRecord.run(Choreographer.java:886)
                                                                                 at android.view.Choreographer.doCallbacks(Choreographer.java:698)
                                                                                 at android.view.Choreographer.doFrame(Choreographer.java:633)
                                                                                 at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:872)
                                                                                 at android.os.Handler.handleCallback(Handler.java:769)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:98)
                                                                             

1. Main2Acitivy.java

public class Main2Activity extends AppCompatActivity {

    private ListView mList;
    private Context mContext;
    private Activity mActivity;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        mContext = this;
        mActivity = this;

        mList = (ListView) findViewById(R.id.list_view);

        List<String> mVideoIDList = new ArrayList<>();
        mVideoIDList.add("KSGYVl4ZgRs");
       // mVideoIDList.add("nCgQDjiotG0");
       // mVideoIDList.add("P3mAtvs5Elc");


        mList.setAdapter(new custom_youtube_list_adapter(mContext,mVideoIDList,mActivity));


        /**
         * @usages
         * check YouTubePlayerFragment is working with main activity or not
         *
         * @status  :  #Working
         */

        /*
         YouTubePlayerFragment youtubeFragment = (YouTubePlayerFragment) getFragmentManager().findFragmentById(R.id.youtubeplayerfragment);
         youtubeFragment.initialize(YOUTUBE_API_KEY,
                new YouTubePlayer.OnInitializedListener() {
                    @Override
                    public void onInitializationSuccess(YouTubePlayer.Provider provider,
                                                        YouTubePlayer youTubePlayer, boolean b) {
                        // do any work here to cue video, play video, etc.
                        youTubePlayer.cueVideo("KSGYVl4ZgRs");
                    }
                    @Override
                    public void onInitializationFailure(YouTubePlayer.Provider provider,
                                                        YouTubeInitializationResult youTubeInitializationResult) {

                    }
                });*/

    }
}

2。 activity_main2.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.youtubecardview.frag_youtube.Main2Activity">

    <ListView
        android:layout_width="wrap_content"
        android:id="@+id/list_view"
        android:layout_height="wrap_content">

    </ListView>

</RelativeLayout>

3。 custom_youtube_list_adapter.java

public class custom_youtube_list_adapter extends BaseAdapter {

    private List<String> aList;
    private Context aContext;
    private Activity aActivity;
    public custom_youtube_list_adapter(Context mContext, List<String> mList, Activity mActivity){

        aList = new ArrayList<>();
        this.aContext = mContext;
        this.aList = mList;
        this.aActivity =mActivity;

    }

    @Override
    public int getCount() {
        return aList.size();
    }

    @Override
    public String getItem(int i) {
        return aList.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
     mHolder  holder;


        LayoutInflater inflater = (LayoutInflater) aContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View v;

        if (convertView == null) {
            v =inflater.from(aContext).inflate(R.layout.custom_frag_youtube_list, null);
            //v = inflater.inflate(R.layout.custom_frag_youtube_list, null);
        } else {
            v = convertView;
        }

        YouTubePlayerFragment youtubeFragment = (YouTubePlayerFragment) aActivity.getFragmentManager().findFragmentById(R.id.youtubeplayerfragment1);

        youtubeFragment.initialize(YOUTUBE_API_KEY,
                new YouTubePlayer.OnInitializedListener() {
                    @Override
                    public void onInitializationSuccess(YouTubePlayer.Provider provider,
                                                        YouTubePlayer youTubePlayer, boolean b) {
                        // do any work here to cue video, play video, etc.
                        youTubePlayer.cueVideo(aList.get(position));
                    }
                    @Override
                    public void onInitializationFailure(YouTubePlayer.Provider provider,
                                                        YouTubeInitializationResult youTubeInitializationResult) {

                    }
                });

        return v;
    }

    class mHolder {

    }
}

4. custom_frag_youtube_list.xml

<?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="wrap_content" >

        <fragment
            android:name="com.google.android.youtube.player.YouTubePlayerFragment"
            android:id="@+id/youtubeplayerfragment1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

</RelativeLayout>

所以,请告诉我我哪里错了?如何解决我的问题?

提前致谢。


更新 1:

我正在使用@azizbekian solution.This 解决了我的膨胀异常问题,但我有多个布局的相同视频。

@Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        View view;
        YouTubePlayerFragment youtubeFragment;
        LayoutInflater inflater = (LayoutInflater) aContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {
            View temp = inflater.inflate(R.layout.custom_frag_youtube_list, parent, false);
            final int id = View.generateViewId();
            temp.setId(id);
            youtubeFragment = YouTubePlayerFragment.newInstance();
            aActivity.getFragmentManager()
                    .beginTransaction()
                    .replace(id, youtubeFragment)
                    .commit();
            view = temp;
            view.setTag(youtubeFragment);
        } else {
            view = convertView;
            youtubeFragment = (YouTubePlayerFragment)view.getTag();
        }

        youtubeFragment.initialize(YOUTUBE_API_KEY,
                new YouTubePlayer.OnInitializedListener() {
                    @Override
                    public void onInitializationSuccess(YouTubePlayer.Provider provider,
                                                        YouTubePlayer youTubePlayer, boolean b) {
                        // do any work here to cue video, play video, etc.
                      Log.e("Youtube Position: ",""+position);
                      Log.e("Youtube list value: ",""+aList.get(position));
                      youTubePlayer.cueVideo(aList.get(position));
                        }
                    @Override
                    public void onInitializationFailure(YouTubePlayer.Provider provider,
                                                        YouTubeInitializationResult youTubeInitializationResult) {

                    }
                });


            return view;
      }

日志值:

Youtube Position:: 0

Youtube list value:: KSGYVl4ZgRs

Youtube Position:: 1

Youtube list value:: nCgQDjiotG0


更新 2:

我已经解决了所有问题而不是一个问题。如果我在播放一个视频后播放视频,那么时间适配器不会刷新。所以我无法一次处理视频播放。

更新 3:

经过大量搜索和@azizbekian 解决方案后,我已经解决了我的问题。通过使用以下解决方案。

 @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {

        final mHolder holder;
        final View fview;
        final LayoutInflater inflater = (LayoutInflater) aContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {

            holder = new mHolder();
            fview = inflater.inflate(R.layout.custom_youtube_frag_listview_list, parent, false);
            holder.mLoaderFrame = (ImageView) fview.findViewById(R.id.imgLayer1);
            fview.setTag(holder);

        } else {
            fview = convertView;
            holder = (mHolder) fview.getTag();
        }

        String VideoID = aList.get(position);

        /**
        * @usages
        * https://img.youtube.com/vi/VideoID/0.jpg
        * 
        * where 
          VideoID is ur youtube video id
          YOUTUBE_THUMBNAIL_URL_VIDEO1  = https://img.youtube.com/vi/
          YOUTUBE_THUMBNAIL_URL_VIDEO2  = /0.jpg
        */

        String mURL = YOUTUBE_THUMBNAIL_URL_VIDEO1 + VideoID + YOUTUBE_THUMBNAIL_URL_VIDEO2;

        Glide.with(aContext).load(mURL).into(holder.mLoaderFrame);
        holder.mLoaderFrame.setVisibility(View.VISIBLE);

        if(mCounterLeaveremove != 0){
            int mId = position+1;

            if(mCounterLeaveremove != mId){
                FragmentManager fragmentManager = aActivity.getFragmentManager();
                Fragment oldFragment = null;
                try {
                    oldFragment = fragmentManager.findFragmentById(mId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(oldFragment != null) {
                    // Delete fragmet from ui, do not forget commit() otherwise no action
                    // is going to be observed
                    fragmentManager.beginTransaction().remove(oldFragment).commit();
                }
            }

        }

        holder.mLoaderFrame.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                mCounterLeaveremove = position+1;

                notifyDataSetChanged();

                YouTubePlayerFragment youtubeFragment;

                final int id = position+1;
                fview.setId(id);
                youtubeFragment = YouTubePlayerFragment.newInstance();

                aActivity.getFragmentManager()
                        .beginTransaction()
                        .replace(id, youtubeFragment)
                        .commit();

                youtubeFragment.initialize(YOUTUBE_API_KEY,
                        new YouTubePlayer.OnInitializedListener() {
                            @Override
                            public void onInitializationSuccess(YouTubePlayer.Provider provider,
                                                                YouTubePlayer youTubePlayer, boolean b) {

                                Log.e("Youtube Position: ", "" + position);
                                Log.e("Youtube list value: ", "" + aList.get(position));

                                holder.mLoaderFrame.setVisibility(View.GONE);

                                String VideoID = aList.get(position);

                                youTubePlayer.loadVideo(VideoID);
                                youTubePlayer.setOnFullscreenListener(new YouTubePlayer.OnFullscreenListener() {
                                    @Override
                                    public void onFullscreen(boolean b) {

                                    }
                                });

                                youTubePlayer.addFullscreenControlFlag(0);

                                /**
                                 * @usages
                                 * 1. Listener use for manage video thumbnail and youtube player
                                 */
                                new custom_youtube_list_adapter.MyPlayerStateChangeListener(holder.mLoaderFrame);
                                new custom_youtube_list_adapter.MyPlaybackEventListener(holder.mLoaderFrame);
                            }

                            @Override
                            public void onInitializationFailure(YouTubePlayer.Provider provider,
                                                                YouTubeInitializationResult youTubeInitializationResult) {

                            }
                        });

            }
        });

        return fview;
    }

要获取youtube视频缩略图,可以去throw。

How do I get a YouTube video thumbnail from the YouTube API?

Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f0b0063, tag null, or parent id 0x7f0b0062 with another fragment for com.google.android.youtube.player.YouTubePlayerFragment

问题是,您正试图膨胀具有相同 ID 的多个片段,这是不可能的。因此,不要将 YouTubePlayerFragment 添加到 xml 文件中,而是在 java 代码中创建它。因此,custom_frag_youtube_list.xml 将更改为以下内容:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

然后在你的适配器中:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ...

    View view;
    YouTubePlayerFragment youtubeFragment;

    if (convertView == null) {
        View temp = inflater.inflate(R.layout.custom_frag_youtube_list, parent, false);
        final int id = View.generateViewId();
        temp.setId(id);
        youtubeFragment = YouTubePlayerFragment.newInstance();
        activity.getFragmentManager()
                .beginTransaction()
                .replace(id, youtubeFragment)
                .commit();
        view = temp;
        view.setTag(youtubeFragment);
    } else {
        view = convertView;
        youtubeFragment = view.getTag();
    }


    // interact with youtubeFragment
    ...

    return view;
}

更新

根据 this thread 判断,Google 似乎不允许同时播放多个 YouTube 视频。