Android视频播放之ViewPager+VideoView

来源:互联网 发布:易语言抄袭vb 编辑:程序博客网 时间:2024/05/20 04:15

由于项目需求,项目主页面有很多个page页面,每个page页面中都有一个VideoView用于播放视频,写次demo用来练手。

源码下载地址

1、上效果图:
这里写图片描述

由于4个page页面的内容一样,所以看起来不好区分,但是功能还是实现了,将就着吧。

2、分析代码:
定义MainActivity.java内部的全局变量:

    ViewPager mViewPager;    MyPagerAdapter mAdapter;    /*** 本地视频路径 ***/    String path = Environment.getExternalStorageDirectory().getPath()            + "/Test.mp4";    // /*** 网络视频路径 ***/    // String path =    // "http://";    /*** 视频路径集合 ***/    String[] paths = new String[] { path, path, path, path };    /*** viewpager的根视图数据集合 ***/    List<ViewGroup> mViewList;    /*** 当前页面索引 ***/    int currentItem = 0;    /*** 上一个页面索引 ***/    int lastItem = 0;    /*** 页面的视频控件集合 ***/    static List<VideoView> mVideoViewList;    /*** 页面播放进度控制器集合 ***/    static List<MediaController> mMediaControllerList;    /*** 页面视频缓冲图集合 ***/    static List<View> mCacheViewList;    /*** 记录每个page页面视频播放的进度 ***/    static Map<Integer, Integer> mCurrentPositions;    /*** 记录每个page页面的视频播放状态 ***/    static Map<Integer, Boolean> mIsPlaying;    // static Map<Integer, Boolean> mIsPageFirstAvaliable;// 记录每个page页面是否第一次加载

然后在oncreate方法中初始化数据:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mViewPager = (ViewPager) this.findViewById(R.id.mViewPager);        initializeData();        Log.e(Tag, "onCreate-------->");    }

initializeData()方法如下:

private void initializeData() {        mViewList = new ArrayList<ViewGroup>();        mVideoViewList = new ArrayList<VideoView>();        mMediaControllerList = new ArrayList<MediaController>();        mCacheViewList = new ArrayList<View>();        mCurrentPositions = new HashMap<Integer, Integer>();        mIsPlaying = new HashMap<Integer, Boolean>();        // mIsPageFirstAvaliable = new HashMap<Integer, Boolean>();        for (int i = 0; i < paths.length; i++) {            ViewGroup v = (ViewGroup) View.inflate(this, R.layout.page_layout,                    null);            VideoView vv = (VideoView) v.findViewById(R.id.mVideoView);            View mView = (View) v.findViewById(R.id.mView);            MediaController mpc = new MediaController(this);            vv.setVideoPath(paths[i]);// 本地视频            // vv.setVideoURI(Uri.parse(path));// 网络视频            vv.setMediaController(mpc);            setListener(vv);            mViewList.add(v);            mVideoViewList.add(vv);            mMediaControllerList.add(mpc);            mCacheViewList.add(mView);            mCurrentPositions.put(i, 0);// 每个页面的初始播放进度为0            mIsPlaying.put(i, true);// 每个页面的初始播放状态false            // mIsPageFirstAvaliable.put(i, true);// 每个页面默认第一次        }        mAdapter = new MyPagerAdapter(this, mViewList);        mViewPager.setAdapter(mAdapter);        mViewPager.setOnPageChangeListener(this);        if (mVideoViewList.get(0) != null) {            mVideoViewList.get(0).start();            mIsPlaying.put(0, true);            // mIsPageFirstAvaliable.put(0, false);        }    }

setlistener方法:

private void setListener(VideoView vv) {        vv.setOnInfoListener(this);        vv.setOnCompletionListener(this);        vv.setOnErrorListener(this);        vv.setOnPreparedListener(this);    }

viewpager的适配器MyPagerAdapter :

class MyPagerAdapter extends android.support.v4.view.PagerAdapter {        Context context;        List<ViewGroup> mViewList;        public MyPagerAdapter(Context context, List<ViewGroup> list) {            this.context = context;            this.mViewList = list;        }        @Override        public int getCount() {            // TODO Auto-generated method stub            return mViewList != null ? mViewList.size() : 0;        }        @Override        public boolean isViewFromObject(View arg0, Object arg1) {            // TODO Auto-generated method stub            return arg0 == (View) arg1;        }        @Override        public void destroyItem(ViewGroup container, int position, Object object) {            // TODO Auto-generated method stub            // super.destroyItem(container, position, object);            container.removeView(mViewList.get(position));        }        @Override        public Object instantiateItem(ViewGroup container, int position) {            // TODO Auto-generated method stub            container.addView(mViewList.get(position));            return mViewList.get(position);        }    }

页面滑动时,需要对视频播放进行记录,并更改页面播放状态,操作放在滑动结束后:

@Override    public void onPageSelected(int pageIndex) {        lastItem = currentItem;        currentItem = pageIndex;        // Log.e(Tag, "currentItem:  " + currentItem);        if (mVideoViewList.get(lastItem) != null) {            if (mVideoViewList.get(lastItem).isPlaying()) {                mIsPlaying.put(lastItem, true);// 记录播放状态                mVideoViewList.get(lastItem).pause();            } else {                mIsPlaying.put(lastItem, false);// 记录播放状态            }            mCurrentPositions.put(lastItem, mVideoViewList.get(lastItem)                    .getCurrentPosition());// 记录播放进度        }        if (mMediaControllerList.get(lastItem) != null) {            if (mMediaControllerList.get(lastItem).isShowing()) {                mMediaControllerList.get(lastItem)                        .setVisibility(View.INVISIBLE);            }        }        if (mVideoViewList.get(currentItem) != null) {            // 如果页面第一次加载            // if (mIsPageFirstAvaliable.get(currentItem)) {            // mIsPlaying.put(currentItem, true);            // mIsPageFirstAvaliable.put(currentItem, false);            // } else {            // 不是第一次加载跳到当前播放进度            mVideoViewList.get(currentItem).seekTo(                    mCurrentPositions.get(currentItem));            // }            if (mIsPlaying.get(currentItem)) {                mVideoViewList.get(currentItem).start();            }            mMediaControllerList.get(currentItem).show(1000);        }    }

当activity失去焦点,停止时也需要进行记录操作:

@Override    protected void onPause() {        // TODO Auto-generated method stub        super.onPause();        if (mVideoViewList.get(currentItem) != null) {            if (mVideoViewList.get(currentItem).isPlaying()) {                mIsPlaying.put(currentItem, true);                mVideoViewList.get(currentItem).pause();            } else {                mIsPlaying.put(currentItem, false);            }            mCurrentPositions.put(currentItem, mVideoViewList.get(currentItem)                    .getCurrentPosition());        }    }

activity销毁时,要清空数据集合,释放内存资源:

@Override    protected void onDestroy() {        // TODO Auto-generated method stub        super.onDestroy();        if (mVideoViewList.get(currentItem) != null) {            mVideoViewList.get(currentItem).stopPlayback();            mVideoViewList.get(currentItem).suspend();        }        clearList();        Log.e(Tag, "onDestroy-------->");    }
/**     * 清空static数据     */    private void clearList() {        mVideoViewList.clear();        mMediaControllerList.clear();        mCacheViewList.clear();        mCurrentPositions.clear();        mIsPlaying.clear();    }

在界面重新对用户可见时,根据记录的播放进度设置进度再判断是否播放:

@Override    protected void onResume() {        // TODO Auto-generated method stub        super.onResume();        if (mVideoViewList.get(currentItem) != null) {            mVideoViewList.get(currentItem).seekTo(                    mCurrentPositions.get(currentItem));            if (mIsPlaying.get(currentItem)) {                mVideoViewList.get(currentItem).start();            }        }    }

另外,还需要给videoview设置相应的监听器,监听器都需要实现各自的方法:

@Override//播放完成监听:    public void onCompletion(MediaPlayer mp) {        if (mVideoViewList.get(currentItem) != null) {            mCurrentPositions.put(currentItem, 0);// 重新播放,进度重置为0            mIsPlaying.put(currentItem, true);// 播放状态:正在播放            mVideoViewList.get(currentItem).resume();            mVideoViewList.get(currentItem).start();        }    }    @Override    public boolean onInfo(MediaPlayer mp, int what, int extra) {        if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {            if (mCacheViewList.get(currentItem) != null) {                mCacheViewList.get(currentItem).setVisibility(View.VISIBLE);            }        } else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {            // 此接口每次回调完START就回调END,若不加上判断就会出现缓冲图标一闪一闪的卡顿现象            if (mp.isPlaying()) {                if (mCacheViewList.get(currentItem) != null) {                    mCacheViewList.get(currentItem).setVisibility(                            View.INVISIBLE);                }            }        }        return true;    }//播放出错监听    @Override    public boolean onError(MediaPlayer mp, int what, int extra) {        // TODO Auto-generated method stub        // 这里设置为true防止弹出对话框,屏蔽原始出错的处理        return true;    }//准备完成监听    @Override    public void onPrepared(MediaPlayer mp) {        // TODO Auto-generated method stub        if (mCacheViewList.get(currentItem) != null) {            mCacheViewList.get(currentItem).setVisibility(View.INVISIBLE);        }        if (mp.isPlaying()) {            // Log.e(Tag, "mp.isPlaying()");        }    }

好了,到这里,viewpager+videoview的开发就完成 了,其中用到的自定义的videoview类在上一篇讲到过,在这里再发一下,WrapVideoView.java:

public class WrapVideoView extends VideoView {    public WrapVideoView(Context context) {        super(context);        requestFocus();    }    public WrapVideoView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public WrapVideoView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int width = getDefaultSize(getWidth(), widthMeasureSpec);        int height = getDefaultSize(getHeight(), heightMeasureSpec);        setMeasuredDimension(width, height);    }    @Override    protected void onDetachedFromWindow() {        // TODO Auto-generated method stub        super.onDetachedFromWindow();    }}

主界面MainActivity.java:

/** * MainActivity 2016-10-18 */public class MainActivity extends Activity implements OnPageChangeListener,        OnPreparedListener, OnErrorListener, OnInfoListener,        OnCompletionListener {    private static final String Tag = "====MainActivity====";    ViewPager mViewPager;    MyPagerAdapter mAdapter;    /*** 本地视频路径 ***/    String path = Environment.getExternalStorageDirectory().getPath()            + "/Test.mp4";    // /*** 网络视频路径 ***/    // String path =    // "http://";    /*** 视频路径集合 ***/    String[] paths = new String[] { path, path, path, path };    /*** viewpager的根视图数据集合 ***/    List<ViewGroup> mViewList;    /*** 当前页面索引 ***/    int currentItem = 0;    /*** 上一个页面索引 ***/    int lastItem = 0;    /*** 页面的视频控件集合 ***/    static List<VideoView> mVideoViewList;    /*** 页面播放进度控制器集合 ***/    static List<MediaController> mMediaControllerList;    /*** 页面视频缓冲图集合 ***/    static List<View> mCacheViewList;    /*** 记录每个page页面视频播放的进度 ***/    static Map<Integer, Integer> mCurrentPositions;    /*** 记录每个page页面的视频播放状态 ***/    static Map<Integer, Boolean> mIsPlaying;    // static Map<Integer, Boolean> mIsPageFirstAvaliable;// 记录每个page页面是否第一次加载    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mViewPager = (ViewPager) this.findViewById(R.id.mViewPager);        initializeData();        Log.e(Tag, "onCreate-------->");    }    private void initializeData() {        mViewList = new ArrayList<ViewGroup>();        mVideoViewList = new ArrayList<VideoView>();        mMediaControllerList = new ArrayList<MediaController>();        mCacheViewList = new ArrayList<View>();        mCurrentPositions = new HashMap<Integer, Integer>();        mIsPlaying = new HashMap<Integer, Boolean>();        // mIsPageFirstAvaliable = new HashMap<Integer, Boolean>();        for (int i = 0; i < paths.length; i++) {            ViewGroup v = (ViewGroup) View.inflate(this, R.layout.page_layout,                    null);            VideoView vv = (VideoView) v.findViewById(R.id.mVideoView);            View mView = (View) v.findViewById(R.id.mView);            MediaController mpc = new MediaController(this);            vv.setVideoPath(paths[i]);// 本地视频            // vv.setVideoURI(Uri.parse(path));// 网络视频            vv.setMediaController(mpc);            setListener(vv);            mViewList.add(v);            mVideoViewList.add(vv);            mMediaControllerList.add(mpc);            mCacheViewList.add(mView);            mCurrentPositions.put(i, 0);// 每个页面的初始播放进度为0            mIsPlaying.put(i, true);// 每个页面的初始播放状态false            // mIsPageFirstAvaliable.put(i, true);// 每个页面默认第一次        }        mAdapter = new MyPagerAdapter(this, mViewList);        mViewPager.setAdapter(mAdapter);        mViewPager.setOnPageChangeListener(this);        if (mVideoViewList.get(0) != null) {            mVideoViewList.get(0).start();            mIsPlaying.put(0, true);            // mIsPageFirstAvaliable.put(0, false);        }    }    private void setListener(VideoView vv) {        vv.setOnInfoListener(this);        vv.setOnCompletionListener(this);        vv.setOnErrorListener(this);        vv.setOnPreparedListener(this);    }    class MyPagerAdapter extends android.support.v4.view.PagerAdapter {        Context context;        List<ViewGroup> mViewList;        public MyPagerAdapter(Context context, List<ViewGroup> list) {            this.context = context;            this.mViewList = list;        }        @Override        public int getCount() {            // TODO Auto-generated method stub            return mViewList != null ? mViewList.size() : 0;        }        @Override        public boolean isViewFromObject(View arg0, Object arg1) {            // TODO Auto-generated method stub            return arg0 == (View) arg1;        }        @Override        public void destroyItem(ViewGroup container, int position, Object object) {            // TODO Auto-generated method stub            // super.destroyItem(container, position, object);            container.removeView(mViewList.get(position));        }        @Override        public Object instantiateItem(ViewGroup container, int position) {            // TODO Auto-generated method stub            container.addView(mViewList.get(position));            return mViewList.get(position);        }    }    @Override    public void onPageScrollStateChanged(int arg0) {    }    @Override    public void onPageScrolled(int arg0, float arg1, int arg2) {    }    @Override    public void onPageSelected(int pageIndex) {        lastItem = currentItem;        currentItem = pageIndex;        // Log.e(Tag, "currentItem:  " + currentItem);        if (mVideoViewList.get(lastItem) != null) {            if (mVideoViewList.get(lastItem).isPlaying()) {                mIsPlaying.put(lastItem, true);// 记录播放状态                mVideoViewList.get(lastItem).pause();            } else {                mIsPlaying.put(lastItem, false);// 记录播放状态            }            mCurrentPositions.put(lastItem, mVideoViewList.get(lastItem)                    .getCurrentPosition());// 记录播放进度        }        if (mMediaControllerList.get(lastItem) != null) {            if (mMediaControllerList.get(lastItem).isShowing()) {                mMediaControllerList.get(lastItem)                        .setVisibility(View.INVISIBLE);            }        }        if (mVideoViewList.get(currentItem) != null) {            // 如果页面第一次加载            // if (mIsPageFirstAvaliable.get(currentItem)) {            // mIsPlaying.put(currentItem, true);            // mIsPageFirstAvaliable.put(currentItem, false);            // } else {            // 不是第一次加载跳到当前播放进度            mVideoViewList.get(currentItem).seekTo(                    mCurrentPositions.get(currentItem));            // }            if (mIsPlaying.get(currentItem)) {                mVideoViewList.get(currentItem).start();            }            mMediaControllerList.get(currentItem).show(1000);        }    }    @Override    public void onCompletion(MediaPlayer mp) {        if (mVideoViewList.get(currentItem) != null) {            mCurrentPositions.put(currentItem, 0);// 重新播放,进度重置为0            mIsPlaying.put(currentItem, true);// 播放状态:正在播放            mVideoViewList.get(currentItem).resume();            mVideoViewList.get(currentItem).start();        }    }    @Override    public boolean onInfo(MediaPlayer mp, int what, int extra) {        if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {            if (mCacheViewList.get(currentItem) != null) {                mCacheViewList.get(currentItem).setVisibility(View.VISIBLE);            }        } else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {            // 此接口每次回调完START就回调END,若不加上判断就会出现缓冲图标一闪一闪的卡顿现象            if (mp.isPlaying()) {                if (mCacheViewList.get(currentItem) != null) {                    mCacheViewList.get(currentItem).setVisibility(                            View.INVISIBLE);                }            }        }        return true;    }    @Override    public boolean onError(MediaPlayer mp, int what, int extra) {        // TODO Auto-generated method stub        // 这里设置为true防止弹出对话框,屏蔽原始出错的处理        return true;    }    @Override    public void onPrepared(MediaPlayer mp) {        // TODO Auto-generated method stub        if (mCacheViewList.get(currentItem) != null) {            mCacheViewList.get(currentItem).setVisibility(View.INVISIBLE);        }        if (mp.isPlaying()) {            // Log.e(Tag, "mp.isPlaying()");        }    }    @Override    protected void onPause() {        // TODO Auto-generated method stub        super.onPause();        if (mVideoViewList.get(currentItem) != null) {            if (mVideoViewList.get(currentItem).isPlaying()) {                mIsPlaying.put(currentItem, true);                mVideoViewList.get(currentItem).pause();            } else {                mIsPlaying.put(currentItem, false);            }            mCurrentPositions.put(currentItem, mVideoViewList.get(currentItem)                    .getCurrentPosition());        }    }    @Override    protected void onDestroy() {        // TODO Auto-generated method stub        super.onDestroy();        if (mVideoViewList.get(currentItem) != null) {            mVideoViewList.get(currentItem).stopPlayback();            mVideoViewList.get(currentItem).suspend();        }        clearList();        Log.e(Tag, "onDestroy-------->");    }    @Override    protected void onResume() {        // TODO Auto-generated method stub        super.onResume();        if (mVideoViewList.get(currentItem) != null) {            mVideoViewList.get(currentItem).seekTo(                    mCurrentPositions.get(currentItem));            if (mIsPlaying.get(currentItem)) {                mVideoViewList.get(currentItem).start();            }        }    }    /**     * 清空static数据     */    private void clearList() {        mVideoViewList.clear();        mMediaControllerList.clear();        mCacheViewList.clear();        mCurrentPositions.clear();        mIsPlaying.clear();    }}

源码下载地址

1 0