2010-04-21 16 views
31

Sto provando a modificare il SurfaceView che uso per fare un'anteprima della fotocamera per visualizzare un quadrato sovrapposto. Tuttavia, il metodo onDraw del SurfaceView esteso non viene mai chiamato.Il metodo onDraw() di SurfaceView esteso non viene mai chiamato

Qui è la fonte:

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

Per la cronologia, sto dicendo che onDraw non viene mai chiamato in base al fatto che il debugger non si ferma mai su un punto di interruzione nel metodo rispetto a un punto di interruzione nel costruttore. L'anteprima della fotocamera, d'altra parte, viene visualizzata correttamente. –

risposta

75

trovato in Android-sviluppatori gruppo Google. Devi semplicemente aggiungere:

setWillNotDraw(false) 

Al costruttore. Ora se qualcuno potesse spiegarmi perché, sarebbe molto apprezzato.

+0

Wow, grazie per questo, mi stavo chiedendo perché il metodo onDraw() di mia vista non sia mai stato chiamato. Vedo il javadoc dice "In genere, se si esegue l'override suDraw (Canvas) è necessario cancellare questo flag.", Quindi probabilmente se si dispone di una vista senza widget sembra che questo debba essere impostato. Solo un'ipotesi :) –

+0

Grazie per la risposta Gab. –

+0

Oh dio, grazie per la risposta, ho avuto un problema diverso ma deriva anche dal non impostare questa bandiera. Era alla ricerca di AGES per una soluzione. – user272043

22

correzione minore:

calcolata setWillNotDraw (falso) alla costruttore causerà crash, perché l'oggetto superficie sottostante non è ancora creata.

Invece, inserire l'istruzione setWillNotDraw (false) nel metodo surfaceCreated(). Questo ritarda la chiamata finché non c'è un oggetto reale con cui lavorare e funziona correttamente.

(e molte grazie agli utenti che hanno pubblicato questa soluzione, ha risolto un grosso problema per me)

+0

Mentre è abbastanza comune per le persone creare sottoclasse di 'SurfaceView' e averlo implementato' SurfaceHolder.Callback', non è richiesto; farlo in 'surfaceCreated' è solo un'opzione se la loro classe lo implementa. In una nota correlata, quali circostanze chiameranno 'setWillNotDraw (false)' nel costruttore causando un arresto anomalo? –

7

Romain Guy explained esso:

Per l'efficienza, i layout non ottengono il loro metodo onDraw() chiamato . Per abilitarlo, chiamare setWillNotDrawEnabled(false) (o impostare l'attributo XML equivalente a falso.)

+0

qual è l'attributo XML equivalente? –

2

Sulla base di tutte le osservazioni di cui sopra ho usato:

Aggiungi setWillNotDraw (false) in caso onAttachedToWindow().

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

e ha funzionato.

Problemi correlati