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
- Android视频播放之ViewPager+VideoView
- Android之VideoView播放视频
- Android之VideoView播放视频
- Android之VideoView播放视频
- Android之VideoView播放视频
- Android播放视频之VideoView
- Android 视频播放之VideoView
- Android开发 之 videoview循环播放视频
- Android开发之使用VideoView播放视频
- Android之使用VideoView播放视频
- Android-多媒体之VideoView视频播放器
- Android 之使用VideoView播放视频
- VideoView之视频播放
- Android VideoView播放视频
- Android VideoView播放视频
- Android VideoView播放视频
- Android VideoView播放视频
- Android VideoView播放视频
- 1011. A+B和C (15)
- Problem 6 Sum square difference (数学)
- 一些有用的unity3d 、webgl网址
- 产品经理(十张图帮你读懂产品经理)
- 查看某个视图某列的含义,不用百度
- Android视频播放之ViewPager+VideoView
- React Native Android 初次试用遇到的各种坑
- Jnetpcap 官方样例 (1)- 捕获数据包
- Linux命令-whereis与which(查找文件)
- 定义的View生成图片文件
- 关于tomcat出现闪退的问题
- 插入排序算法代码
- iOS 图片轮播
- Zygote