2010-04-21 6 views
31

Estoy tratando de modificar el SurfaceView que uso para hacer una vista previa de la cámara para mostrar un recuadro superpuesto. Sin embargo, el método onDraw del SurfaceView extendido nunca se llama.Método extendido de OnView() de SurfaceView nunca llamado

Aquí está la fuente:

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

Para el registro, digo onDraw nunca se llama en función del hecho de que el depurador nunca se detiene en un punto de interrupción en el método en lugar de un punto de interrupción en el constructor. La vista previa de la cámara, por otro lado, se muestra correctamente. –

Respuesta

75

encontró en el Android-desarrolladores grupo de Google. Simplemente tiene que agregar:

setWillNotDraw(false) 

Para el constructor. Ahora si alguien pudiera explicarme por qué, sería muy apreciado.

+0

Guau, gracias por esto, me preguntaba por qué el método onDraw() de mi vista nunca se llamó. Veo que el javadoc dice "Normalmente, si anula OnDraw (Canvas), debe borrar este indicador", por lo que probablemente si tiene una Vista sin widgets, parece que se debe configurar. Solo una conjetura :) –

+0

Gracias por la respuesta Gab. –

+0

Oh dios gracias por la respuesta, tuve un problema diferente, pero también se derivó de no establecer esta bandera. Había estado buscando AGES para una solución. – user272043

22

pequeña corrección:

Adición setWillNotDraw (falso) al constructor causarán choques, porque el objeto de la superficie subyacente no ha sido creada todavía.

En su lugar, coloque la sentencia setWillNotDraw (false) en el método surfaceCreated(). Esto demora la llamada hasta que haya un objeto real para trabajar y funcione correctamente.

(y muchas gracias a los usuarios que han publicado esta solución, se soluciona un problema importante para mí)

+0

Si bien es bastante común que las personas subclases 'SurfaceView' y que implementen' SurfaceHolder.Callback', no es necesario; hacerlo en 'surfaceCreated' es solo una opción si su clase lo implementa. En una nota relacionada, ¿qué circunstancias llamarán 'setWillNotDraw (false)' en el constructor causando un bloqueo? –

7

Romain individuo explained que:

Para una mayor eficacia, los diseños no consiguen su método onDraw() llamada . Para activarlo, llame setWillNotDrawEnabled(false) (o conjunto de atributos el equivalente XML en false.)

+0

¿cuál es el atributo XML equivalente? –

2

Sobre la base de todos los comentarios anteriores que he utilizado:

Añadir setWillNotDraw (falso) en caso onAttachedToWindow().

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

y funcionó.

Cuestiones relacionadas