美文网首页UI
RecyclerView中播放视频

RecyclerView中播放视频

作者: 这个杀手不太累 | 来源:发表于2017-10-22 19:03 被阅读427次

    在很多播放视频的APP中都有在列表中播放视频的效果,当点击播放的时候,在列表中播放,当视频列表滑动出屏幕的时候,就在屏幕的右下角播放。大致效果如下图:


    这里写图片描述
    • 主要思路

      1. 在和RecyclerView的同级布局文件中,在右下角放置一个隐藏FrameLayout,当正在播放的列表滑出界面的时候,将右下角的FragmeLayout设置为显示,并将播放的SurfaceView添加到右下角的FragmeLayout播放。
      2. 在列表的ViewHolder布局文件中放置一个FragmeLayout,当点击播放按钮时,将SurfaceView添加到FragmentLayout中播放。
      3. 为RecyclerView设置addOnChildAttachStateChangeListener事件,这个监听有两个重要的方法
      /**
       *当添加子View时回调
       */
      public void onChildViewAttachedToWindow(View view);
      
      /**
       *当移除子View时回调
       */
      public void onChildViewDetachedFromWindow(View view)
      
    • 首先看下主界面布局代码:

    <?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">
    
        <android.support.design.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <android.support.design.widget.AppBarLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="@color/colorPrimary"
                    app:layout_scrollFlags="scroll|enterAlways|snap" />
            </android.support.design.widget.AppBarLayout>
    
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
        </android.support.design.widget.CoordinatorLayout>
    
        <!-- 右下角的FragmeLayout -->
        <FrameLayout
            android:id="@+id/video_root_fl"
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:background="#000"
            android:visibility="gone" />
    
        <!--全屏播放的FragmeLayout-->
        <FrameLayout
            android:id="@+id/video_full_screen"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
    </RelativeLayout>
    
    

    可以在布局文件中看到,在右下角中放置了一个隐藏的FrameLayout,当正在播放的列表滑出界面时我们会使用这个FrameLayout来放置播放视频的SurfaceView。

    • 在RecyclerView中的item布局文件中也有一个FrameLayout
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/item_cardview"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_margin="10dp"
        android:background="#fff"
        android:elevation="8dp"
        android:padding="5dp"
        app:cardBackgroundColor="#fff"
        app:cardCornerRadius="5dp">
    
        <!--列表播放使用的FrameLayout-->
        <FrameLayout
            android:id="@+id/item_video_root_fl"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
    
        <ImageView
            android:id="@+id/item_imageview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop" />
    
        <ImageView
            android:id="@+id/item_image_play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/ic_play_circle_outline_white_48dp" />
    </android.support.v7.widget.CardView>
    

    item中这个FrameLayout用于点击列表中播放按钮将要播放的SurfaceView添加到这个FrameLayout中

    • 为RecyclerView添加addOnChildAttachStateChangeListener监听,当正在播放的item滑出界面时会回调onChildViewDetachedFromWindow这个方法,我们在这个方法中判断如果FragmeLayout中有视频播放,将右下角的FrameLayout设置为显示,移除item布局中的SurfaceView并将其添加到右下角的FrameLayout,将记录这个item的位置,当再次将这个item滑动到界面中时,会回调onChildViewAttachedToWindow这个方法。同理再将这个右下角中的FrameLayout中的SurfaceView移除并设置为隐藏,再将SurfaceView添加到item中的FrameLayout播放。
        //为RecyclerView添加addOnChildAttachStateChangeListener监听
    recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
                @Override
                public void onChildViewAttachedToWindow(View view) {
                    if (videoPosition == -1 || videoRootViewFl.getVisibility() != View.VISIBLE) {
                        return;
                    }
                    if (videoPosition == recyclerView.getChildAdapterPosition(view)) {
                        videoPosition = -1;
                        showVideo(view, VIDEO_PATH);
                    }
                }
    
                @Override
                public void onChildViewDetachedFromWindow(View view) {
                    if (videoView == null || videoRootViewFl.getVisibility() == View.VISIBLE) return;
                    View v = view.findViewById(R.id.item_video_root_fl);
                    if (v != null) {
                        FrameLayout fl = (FrameLayout) v;
                        videoPosition = recyclerView.getChildAdapterPosition(view);
                        if (fl.getChildCount() > 0) {
                            fl.removeAllViews();
                            int position = 0;
                            if (videoView.isPlaying()) {
                                position = videoView.getPosition();
                                videoView.stop();
                            }
                            videoRootViewFl.setVisibility(View.VISIBLE);
                            videoRootViewFl.removeAllViews();
                            lastView = videoRootViewFl;
                            videoRootViewFl.addView(videoView, new ViewGroup.LayoutParams(-1, -1));
                            videoView.setVideoPath(VIDEO_PATH);
                            videoView.start();
                            videoView.seekTo(position);
    //                        if (videoView.isPause()) {
    //                            videoView.resume();
    //                        }
                        }
                        fl.setVisibility(View.GONE);
                    }
                    v = view.findViewById(R.id.item_imageview);
                    if (v != null) {
                        if (v.getVisibility() != View.VISIBLE) {
                            v.setVisibility(View.VISIBLE);
                        }
                    }
                    v = view.findViewById(R.id.item_image_play);
                    if (v != null) {
                        if (v.getVisibility() != View.VISIBLE) {
                            v.setVisibility(View.VISIBLE);
                        }
                    }
                }
            });
    

    完整代码
    传送门

    相关文章

      网友评论

        本文标题:RecyclerView中播放视频

        本文链接:https://www.haomeiwen.com/subject/hzlnuxtx.html