2010-04-21 17 views
31

Próbuję zmodyfikować SurfaceView używam do robienia podglądu kamery, aby wyświetlić nakładający się kwadrat. Jednak metoda onDraw rozszerzonego SurfaceView nigdy nie jest wywoływana.Metoda onDraw (Expand) Extended SurfaceView nigdy nie była wywoływana

Oto źródło:

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

Na potrzeby zapisu mówię, że onDraw nigdy nie jest wywoływany w oparciu o fakt, że debugger nigdy nie zatrzymuje się na punkcie przerwania w metodzie, w przeciwieństwie do punktu przerwania w konstruktorze. Z drugiej strony podgląd kamery wyświetla się poprawnie. –

Odpowiedz

75

Znaleziono go na android-developers grupy Google. Trzeba po prostu dodać:

setWillNotDraw(false) 

Do konstruktora. Teraz, jeśli ktoś mógłby mi wytłumaczyć dlaczego, byłoby to bardzo cenne.

+0

Wow, dziękuję za to, zastanawiałem się, dlaczego moja metoda onDraw() nie została wywołana. Widzę, że javadoc mówi: "Zazwyczaj, jeśli przesłonisz OnDraw (Canvas), powinieneś wyczyścić tę flagę.", Więc prawdopodobnie jeśli masz widok bez żadnych widżetów, wydaje się, że trzeba to ustawić. Tylko zgadnij :) –

+0

Dzięki za odpowiedź Gab. –

+0

O Boże dzięki za odpowiedź, miałem inny problem, ale wynikało to również z tego, że nie ustawiłem tej flagi. Szukałem rozwiązania AGES dla rozwiązania. – user272043

22

Minor korekta:

Dodawanie setWillNotDraw (fałsz) do konstruktoraspowoduje awarii, ponieważ podstawowa Powierzchnia obiektu nie został jeszcze utworzony.

Zamiast tego, umieść instrukcję setWillNotDraw (false) w metodzie surfaceCreated(). Spowoduje to opóźnienie połączenia, dopóki nie pojawi się prawdziwy obiekt do pracy i działa poprawnie.

(i wiele dzięki użytkowników Kto pisał tego rozwiązania, to rozwiązać poważny problem dla mnie)

+0

Podczas gdy jest dość powszechne, aby ludzie podklasy 'SurfaceView' i mają zaimplementować' SurfaceHolder.Callback', nie jest to wymagane; zrobienie tego w 'surfaceCreated' jest tylko opcją, jeśli ich klasa to zaimplementuje. W pokrewnej notatce, jakie okoliczności wywołają w konstruktorze 'setWillNotDraw (false)' powodują awarię? –

7

Romain Guy explained go:

Dla zwiększenia efektywności układów nie dostać ich metody onDraw() nazwie . Aby ją włączyć, należy zadzwonić setWillNotDrawEnabled(false) (lub ustawić atrybut równoważne XML false.)

+0

Jaki jest równoważnik atrybutu XML? –

2

Na podstawie wszystkich powyższych uwag użyłem:

Dodaj setWillNotDraw (fałsz) w onAttachedToWindow() zdarzenia.

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

i to działało.

Powiązane problemy