由于项目需求,项目主页面有很多个page页面,每个page页面中都有一个VideoView用于播放视频,写次demo用来练手。
源码下载地址
1、上效果图:
由于4个page页面的内容一样,所以看起来不好区分,但是功能还是实现了,将就着吧。
2、分析代码:
定义MainActivity.java内部的全局变量:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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方法中初始化数据:
复制代码
1
2
3
4
5
6
7
8
@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()方法如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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方法:
复制代码
1
2
3
4
5
6
private void setListener(VideoView vv) {
vv.setOnInfoListener(this);
vv.setOnCompletionListener(this);
vv.setOnErrorListener(this);
vv.setOnPreparedListener(this);
}
viewpager的适配器MyPagerAdapter :
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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);
}
}
页面滑动时,需要对视频播放进行记录,并更改页面播放状态,操作放在滑动结束后:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@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失去焦点,停止时也需要进行记录操作:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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销毁时,要清空数据集合,释放内存资源:
复制代码
1
2
3
4
5
6
7
8
9
10
11
@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-------->");
}
复制代码
1
2
3
4
5
6
7
8
9
10
/**
* 清空static数据
*/
private void clearList() {
mVideoViewList.clear();
mMediaControllerList.clear();
mCacheViewList.clear();
mCurrentPositions.clear();
mIsPlaying.clear();
}
在界面重新对用户可见时,根据记录的播放进度设置进度再判断是否播放:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
@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设置相应的监听器,监听器都需要实现各自的方法:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@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:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/**
* 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();
}
}
源码下载地址
最后
以上就是典雅信封最近收集整理的关于Android视频播放之ViewPager+VideoView的全部内容,更多相关Android视频播放之ViewPager+VideoView内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复