2012-08-29 23 views
3

我想編碼的視頻播放器,它播放視頻,但我無法調整SurfaceView的大小。 MediaPlayer準備好後,我設置了我想要的大小,然後調用requestLayout或forceLayout,但沒有附加任何內容。我logcat的說:即使forceLayout()不起作用時,如何強制執行requestLayout()?

08-29 17:42:38.915: I/SEC_Overlay(2707): overlay_setParameter param[4]=0 
08-29 17:42:38.915: D/SEC_Overlay(2707): dst width, height have changed [w= 480, h= 800] -> [w=480, h= 800] 
08-29 17:42:38.915: I/SEC_Overlay(2707): Nothing to do! 

顯然,它嘗試調整,但發現沒有什麼變化,不叫onMesured或onLayout

我的代碼:

public class VideoSurface extends ViewGroup { 
private final String TAG = "VideoSurface"; 
protected int mWidth = 0 ; 
protected int mHeight = 0 ; 
protected SurfaceView mSurfaceView; 
protected SurfaceHolder mHolder; 

public VideoSurface(Context context) { 
    super(context); 
    init(context); 
} 
public VideoSurface(Context context, AttributeSet attrs) { 
    super(context,attrs); 
    init(context); 
} 
public VideoSurface(Context context, AttributeSet attrs, int defStyle) { 
    super(context,attrs,defStyle); 
    init(context); 
} 


private void init(Context context){ 
    // Install a SurfaceHolder.Callback so we get notified when the 
    // underlying surface is created and destroyed. 
    mSurfaceView = new SurfaceView(context); 
    this.addView(mSurfaceView); 

    // Install a SurfaceHolder.Callback so we get notified when the 
    // underlying surface is created and destroyed. 
    mHolder=mSurfaceView.getHolder() ; 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 

public Surface getSurface(){return mHolder.getSurface();} 
public void setSize(Size size){ 
    mWidth = size.width ; 
    mHeight = size.height ; 
} 
public void setSize(int w,int h){ 
    mWidth = w ; 
    mHeight = h ; 
} 

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    // We purposely disregard child measurements because act as a 
    // wrapper to a SurfaceView that centers the camera preview instead 
    // of stretching it. 
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
    setMeasuredDimension(width, height); 
    Log.d(TAG,"onMeasure:"+width+"x"+height); 
} 

@Override 
protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    if (changed && getChildCount() > 0) { 
     final View child = getChildAt(0); 

     final int width = r - l; 
     final int height = b - t; 

     int previewWidth = width; 
     int previewHeight = height; 
     if ((mWidth != 0)&&(mHeight != 0)) { 
      previewWidth = mWidth; 
      previewHeight = mHeight; 
     } 
     Log.d(TAG,"onLayout L1: Desired:"+mWidth+"x"+mHeight+" Actual:"+previewWidth+"x"+previewHeight); 

     // Center the child SurfaceView within the parent. 
     if (width * previewHeight > height * previewWidth) { 
      final int scaledChildWidth = previewWidth * height/previewHeight; 
      child.layout((width - scaledChildWidth)/2, 0, 
        (width + scaledChildWidth)/2, height); 
     } else { 
      final int scaledChildHeight = previewHeight * width/previewWidth; 
      child.layout(0, (height - scaledChildHeight)/2, 
        width, (height + scaledChildHeight)/2); 
     } 
    } 
    Log.d(TAG,"onLayout L2:"+l+", "+t+", "+r+", "+b); 
} 

而且herited類:

public class PlayerView extends VideoSurface implements SurfaceHolder.Callback { 
private static final String TAG = "PlayerView"; 
private MediaPlayer mPlayer = new MediaPlayer() ; 
private String mVideoPath = "" ; 

public PlayerView(Context context) { 
    super(context); 
    init(); 
} 
public PlayerView(Context context, AttributeSet attrs) { 
    super(context,attrs); 
    init(); 
} 
public PlayerView(Context context, AttributeSet attrs, int defStyle) { 
    super(context,attrs,defStyle); 
    init(); 
} 

private void init(){ 
    mHolder.addCallback(this); 

    mPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener(){ 
     @Override 
     public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 
      //TODO 
      mHolder.setFixedSize(width,height); 
      setSize(width,height) ; 
      setLayoutParams(new LayoutParams(width, height)); 
      requestLayout() ; 
      forceLayout(); 
      Log.d(TAG,"Size:"+width+"x"+height); 
     } 
    }); 
    mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
     @Override 
     public void onPrepared(MediaPlayer mp) { 
      // TODO 
      setSize(mPlayer.getVideoWidth(), mPlayer.getVideoHeight()); 
      mPlayer.start(); 
      Log.d(TAG,"Started"); 
     } 
    }); 

    //TODO DEBUG 
    mVideoPath = Environment.getExternalStorageDirectory().getPath()+"/external_sd/USB Storage/test.mp4" ; 
} 

private void prepareVideo(String path){ 
    stop() ; 
    try { 
     mPlayer.setDataSource(path) ; 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    //TODO 
    //mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 

    mPlayer.prepareAsync() ; 
} 

public void start(String path) { 
    mVideoPath = path ; 
    if (!mHolder.isCreating()){ 
     prepareVideo(path) ; 
    } 
} 

public void stop() { 
    if (mPlayer.isPlaying()) { 
     mPlayer.stop(); 
    } 
    mPlayer.reset(); 
} 

public void onStop(){ 
    stop() ; 
    mPlayer.release(); 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    mPlayer.setDisplay(mHolder); 
    if(!mVideoPath.isEmpty()){ 
     prepareVideo(mVideoPath) ; 
    } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
} 

}

如何在甚至forceLayout()不起作用時強制執行requestLayout()?

回答

1

您可以使用requestLayout();強迫你的佈局重繪所以,你需要調用

yourLayout.requestLayout();init()