VideoView 是android 系统提供的一个媒体播放显示和控制的控件。其结构层次如下:
原型:VideoView extends SurfaceView implements MediaController.MediaPlayerControl
类结构:
java.lang.Object
↳ android.view.View
↳ android.view.SurfaceView
↳ android.widget.VideoView
VideoPlayerDemo.zip
原型:VideoView extends SurfaceView implements MediaController.MediaPlayerControl
类结构:
java.lang.Object
↳ android.view.View
↳ android.view.SurfaceView
↳ android.widget.VideoView
通过VideoView 的原型可知:如果构建更为复杂和有特色个性的视频View,需要继承SurfaceView 和实现MediaPlayerControl接口。其中
SurfaceView 为显示提供支持,MediaPlayerControl则为媒体控制提供了支持。但是如果只是想进行简单的修改,比如添加自定义的view或
者修改其自身view的样式,这完全可以通过继承MediaController来实现
自定义一个类继承MediaController
public class MediaController extends android.widget.MediaController
重写setAnchorView方法,在这里可以添加自定义的view或者修改其自身view
@Override
public void setAnchorView(View view) {
super.setAnchorView(view);
mView = LayoutInflater.from(getContext()).inflate(
R.layout.video_button, null);
try {
SeekBar sb = (SeekBar) LayoutInflater.from(getContext()).inflate(
R.layout.video_seekbar, null);
Field mRoot = android.widget.MediaController.class
.getDeclaredField("mRoot");
mRoot.setAccessible(true);
ViewGroup mRootVg = (ViewGroup) mRoot.get(this);
ViewGroup vg = findSeekBarParent(mRootVg);
int index = 1;
for (int i = 0; i < vg.getChildCount(); i++) {
if (vg.getChildAt(i) instanceof SeekBar) {
index = i;
break;
}
}
vg.removeViewAt(index);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.weight = 1;
vg.addView(sb, index, params);
Field mProgress = android.widget.MediaController.class
.getDeclaredField("mProgress");
mProgress.setAccessible(true);
mProgress.set(this, sb);
Field mSeekListener = android.widget.MediaController.class
.getDeclaredField("mSeekListener");
mSeekListener.setAccessible(true);
sb.setOnSeekBarChangeListener((OnSeekBarChangeListener) mSeekListener
.get(this));
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private ViewGroup findSeekBarParent(ViewGroup vg) {
ViewGroup viewGroup = null;
for (int i = 0; i < vg.getChildCount(); i++) {
View view = vg.getChildAt(i);
if (view instanceof SeekBar) {
viewGroup = (ViewGroup) view.getParent();
break;
} else if (view instanceof ViewGroup) {
viewGroup = findSeekBarParent((ViewGroup) view);
} else {
continue;
}
}
return viewGroup;
}
重写show和hide方法,让MediaController来控制自定义view的隐藏和显示
@Override
public void show(int timeout) {
super.show(timeout);
((ViewGroup) mActivity.findViewById(android.R.id.content))
.removeView(mView);
((ViewGroup) mActivity.findViewById(android.R.id.content))
.addView(mView);
}
@Override
public void hide() {
super.hide();
((ViewGroup) mActivity.findViewById(android.R.id.content))
.removeView(mView);
}
VideoPlayerDemo.zip