2013-10-09 74 views
6

我注意到在Fragment中有一個MediaControllerVideoView的位置有問題。 下面是它的外觀在Nexus 7上運行Android 4.3的截圖: Screenshot of app with MediaController on 4.3在片段中放置MediaController

而這裏的應用程序在Nexus 7的屏幕截圖運行Android 4.2.2: enter image description here

正如你所看到的,位置的MediaController處於API 17或更低版​​本的活動中間(在另一臺使用4.1.2的平板電腦上進行測試)。我注意到MediaController的大小是正確的。

我的片段顯示在FrameLayout中,其寬度由它的權重(此處爲0.6)定義,所以不是通過特定的dpi值。

我檢查了MediaController的源代碼Grepcode,並將4.3中的一個與4.2.2的代碼進行了比較,並且對LayoutParams有一些小的更改,但是我找不到一種方法來實現此功能。

我初始化我VideoView和MediaController在我的片段onActivityCreated()

mMediaController = new MediaController(getActivity()); 
mMediaController.setAnchorView(videoView); 
videoView.setMediaController(mMediaController); 

是否有人知道如何定位是正確的?

回答

2

首先,我們需要定製的MediaController改變它在之前的Android 4.3

class CustomMediaController extends MediaController 
{ 

    public CustomMediaController(Context context) { 
     super(context); 
    } 

    public CustomMediaController(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    } 

    public CustomMediaController(Context context, boolean useFastForward) { 
     super(context, useFastForward); 
    } 

    @Override 
    public void show(int timeout) { 
     super.show(timeout); 
     int currentapiVersion = android.os.Build.VERSION.SDK_INT; 
     if (currentapiVersion < 18) //android.os.Build.VERSION_CODES.JELLY_BEAN_MR2 
     { 
      try { 
       Field field1 = MediaController.class.getDeclaredField("mAnchor"); 
       field1.setAccessible(true); 
       View mAnchor = (View)field1.get(controller); 

       Field field2 = MediaController.class.getDeclaredField("mDecor"); 
       field2.setAccessible(true); 
       View mDecor = (View)field2.get(controller); 

       Field field3 = MediaController.class.getDeclaredField("mDecorLayoutParams"); 
       field3.setAccessible(true); 
       WindowManager.LayoutParams mDecorLayoutParams = (WindowManager.LayoutParams)field3.get(controller); 

       Field field4 = MediaController.class.getDeclaredField("mWindowManager"); 
       field4.setAccessible(true); 
       WindowManager mWindowManager = (WindowManager)field4.get(controller); 

       int [] anchorPos = new int[2]; 
       mAnchor.getLocationOnScreen(anchorPos); 

       // we need to know the size of the controller so we can properly position it 
       // within its space 
       mDecor.measure(MeasureSpec.makeMeasureSpec(mAnchor.getWidth(), MeasureSpec.AT_MOST), 
           MeasureSpec.makeMeasureSpec(mAnchor.getHeight(), MeasureSpec.AT_MOST)); 

       WindowManager.LayoutParams p = mDecorLayoutParams; 
       p.width = mAnchor.getWidth(); 
       p.x = anchorPos[0] + (mAnchor.getWidth() - p.width)/2; 
       p.y = anchorPos[1] + mAnchor.getHeight() - mDecor.getMeasuredHeight(); 
       mWindowManager.updateViewLayout(mDecor, mDecorLayoutParams); 

      } catch (Exception e) { 
        e.printStackTrace(); 
      } 
     } 
    } 
} 

怪異的行爲然後只需更換的MediaController與CustomMediaController變量聲明,一切都會做。原因是4.3之前的android代碼被竊聽。我們使用反射來修正show()方法中的位置。

經測試與android 4.0。

+0

什麼是「控制器」對象? – kmas

+0

什麼是控制器? – delive