關於對Android的videoView和mediaController的吐槽
http://my.oschina.net/mastere/blog/164628
這幾天在做視訊播放器一直在研究videoview。
videoview是和video連用的。2個元件分別都提供一個方法關聯另一方:
mediaController-setAnchorView(videoview),videoview-setMediaController(mediaController)。
我習慣在一個佈局檔案中設定好videoview的位置之後,在activity的onCreate()中將mediaController
動態初始化並關聯到已經設定好的videoview上。
但是這裡的說明下在佈局中設定videoview的時候最好給videoview外面單獨套一個的容器。
當然這個外層容器的高度要設定為wrap_content。這樣就會把視訊播放器和控制器很好的組合在一起。
這裡我用的是線性佈局LinearLayout因為我不想控制器把視訊給遮蓋住了。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id= "@+id/main_videoview_contianer">
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
實現的效果圖如圖:
用的是模擬器。所以視訊沒有播放出來成了黑色的。
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
如果videoview的外層容器的高度是match_parent或者fillparent的話。
視訊控制器會和視訊播放器分離如圖:灰色為分離的部分。
PS: 不過其實你也可以先在佈局檔案中將mediaController設定好,然後在程式碼中初始話videoview然後將videoview新增到mediacontroller中去,因為mediaController是繼承frameLayout的本身就是一個幀式佈局容器:
下面是設定mediaController的方法
public void setAnchorView(View view) {
if (mAnchor != null) {
mAnchor.removeOnLayoutChangeListener(mLayoutChangeListener);
}
mAnchor = view;
if (mAnchor != null) {
mAnchor.addOnLayoutChangeListener(mLayoutChangeListener);
}
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
removeAllViews();
View v = makeControllerView();
addView(v, frameParams);
}
從官方原始碼中可以看出,video會強制撐滿全屏mediacontroller.
mediaController主要實現對videoview的播放控制,但是翻開mediacontroller的原始碼才發現。
mediaController能實現的功能太少了。其實這些都可以忍受,唯一讓人不能忍受的的mediaController
暴露的可以讓繼承的類覆蓋的方法太少了。
而且提供的監聽器只有上一首和下一首。無法監聽快進和後退。但是mediaController的快進是固定的15秒快進和固定的5秒後退時間。
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
final boolean uniqueDown = event.getRepeatCount() == 0
&& event.getAction() == KeyEvent.ACTION_DOWN;
if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
|| keyCode == KeyEvent.KEYCODE_SPACE) {
if (uniqueDown) {
doPauseResume();
show(sDefaultTimeout);
if (mPauseButton != null) {
mPauseButton.requestFocus();
}
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY ) {//鍵盤播放健
if (uniqueDown && !mPlayer.isPlaying()) {
mPlayer.start();
updatePausePlay();
show(sDefaultTimeout);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP //鍵盤停止鍵
|| keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {//鍵盤暫停鍵
if (uniqueDown && mPlayer.isPlaying()) {
mPlayer.pause();
updatePausePlay();
show(sDefaultTimeout);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN //聲音下調鍵
|| keyCode == KeyEvent.KEYCODE_VOLUME_UP //聲音上調鍵
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE //靜音鍵
|| keyCode == KeyEvent.KEYCODE_CAMERA) { //開啟相機鍵
// don't show the controls for volume adjustment
return super.dispatchKeyEvent(event);
} else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
if (uniqueDown) {
hide();
}
return true;
}
show(sDefaultTimeout);
return super.dispatchKeyEvent(event);
}
很明顯我們可以看到,mediaController的設計時間早完全是針對那些有鍵盤的手機,現在的手機那裡會有什麼播放和暫停鍵。