1. 程式人生 > >關於對Android的videoView和mediaController的吐槽

關於對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的設計時間早完全是針對那些有鍵盤的手機,現在的手機那裡會有什麼播放和暫停鍵。