2010-04-21 53 views
31

我想修改SurfaceView我用來做一個相機預覽,以顯示一個覆蓋的正方形。但是,擴展SurfaceView的onDraw方法永遠不會被調用。擴展SurfaceView的onDraw()方法從來沒有叫

這裏是源:

public class CameraPreviewView extends SurfaceView { 

    protected final Paint rectanglePaint = new Paint(); 

    public CameraPreviewView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     rectanglePaint.setARGB(255, 200, 0, 0); 
     rectanglePaint.setStyle(Paint.Style.FILL); 
     rectanglePaint.setStrokeWidth(2); 
    } 

    @Override 
    protected void onDraw(Canvas canvas){ 
     canvas.drawRect(new Rect(10,10,200,200), rectanglePaint); 
     Log.w(this.getClass().getName(), "On Draw Called"); 
    } 
} 

public class CameraPreview extends Activity implements SurfaceHolder.Callback{ 

    private SurfaceHolder holder; 
    private Camera camera; 

    @Override 
    protected void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 

     // We remove the status bar, title bar and make the application fullscreen 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     // We set the content view to be the layout we made 
     setContentView(R.layout.camera_preview); 

     // We register the activity to handle the callbacks of the SurfaceView 
     CameraPreviewView surfaceView = (CameraPreviewView) findViewById(R.id.camera_surface); 
     holder = surfaceView.getHolder(); 

     holder.addCallback(this); 
     holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

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

     Camera.Parameters params = camera.getParameters(); 

     params.setPreviewSize(width, height); 
     camera.setParameters(params); 

     try { 
      camera.setPreviewDisplay(holder); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     camera.startPreview(); 

    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     camera = Camera.open(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     camera.stopPreview(); 
     camera.release(); 
    } 


} 
+0

爲了記錄,我說onDraw從來沒有被調用,基於這樣一個事實,即調試器永遠不會停止在方法中的斷點上,而不是構造函數中的斷點。另一方面,相機預覽顯示正確。 – 2010-04-21 22:31:55

回答

75

發現它在Android的開發者谷歌組。您只需添加:

setWillNotDraw(false) 

給構造函數。現在如果有人能解釋我爲什麼,那將不勝感激。

+0

哇,謝謝你,我想知道爲什麼我的View的onDraw()方法從未被調用。我看到javadoc說:「通常情況下,如果你重寫onDraw(Canvas),你應該清除這個標誌。」,所以如果你有一個沒有任何小部件的View,它似乎需要設置。只是一個猜測:) – 2011-01-16 18:06:22

+0

感謝您的答案Gab。 – 2011-03-13 01:21:32

+0

哦,上帝謝謝你的答案,我有一個不同的問題,但它也源於不設置此標誌。一直在尋找AGES解決方案。 – user272043 2011-09-04 13:16:43

22

次要校正:

添加setWillNotDraw(假)至構造將導致崩潰,這是因爲下面的表面對象尚未建立。

取而代之,將setWillNotDraw(false)語句放入surfaceCreated()方法中。這延遲了通話,直到有一個真正的對象可以使用,並且正常工作。

(和許多感謝誰張貼了這個解決方案的用戶,它解決了我的一個主要問題)

+0

中派生出來。雖然人們很普遍的使用子類「SurfaceView」並讓它實現「SurfaceHolder.Callback」,但這不是必需的;在'surfaceCreated'中做它只是一個選項,如果他們的類實現它。在相關說明中,在構造函數中調用'setWillNotDraw(false)'會導致崩潰的是什麼情況? – 2012-09-06 07:56:56

7

羅曼蓋伊explained它:

爲了提高效率,佈局沒有得到他們的onDraw()方法稱爲。要 啓用它,調用setWillNotDrawEnabled(false)(或設置相當於 XML屬性設置爲false。)

+0

什麼是等同的XML屬性? – 2013-07-11 21:25:36

2

基於我所使用的所有上述評論:

在onAttachedToWindow()事件添加setWillNotDraw(假)。

@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); setWillNotDraw(false); }

和它的工作。