2010-04-21 4 views
31

Я пытаюсь изменить SurfaceView, который я использую для предварительного просмотра камеры, чтобы отобразить перекрывающий квадрат. Однако метод onDraw расширенного SurfaceView никогда не вызывается.Метод onDraw() Extended SurfaceView никогда не назывался

Вот источник:

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 никогда не вызывается на основании того факта, что отладчик никогда не останавливается на контрольной точке в методе, а не в точке останова в конструкторе. С другой стороны, предварительный просмотр камеры отображается правильно. –

ответ

75

Нашел на андроид-группой разработчиков Google. Вам просто нужно добавить:

setWillNotDraw(false) 

К конструктору. Теперь, если кто-то может объяснить мне, почему, это было бы очень полезно.

+0

Ничего себе, спасибо за это, мне было интересно, почему мой метод onDraw() не был вызван. Я вижу, что javadoc говорит: «Как правило, если вы переопределяете onDraw (Canvas), вы должны очистить этот флаг.», Поэтому, вероятно, если у вас есть View без каких-либо виджетов, похоже, это необходимо установить. Просто догадаться :) –

+0

Спасибо за ответ Gab. –

+0

О, боже, спасибо за ответ, у меня была другая проблема, но это также связано с не установкой этого флага. Был поиск AGES для решения. – user272043

22

Незначительные коррекции:

Добавление setWillNotDraw (ложный) в конструктор будут вызывать сбои, потому что основная поверхность объект еще не созданы.

Вместо этого поставьте инструкцию setWillNotDraw (false) в метод surfaceCreated(). Это задерживает вызов до тех пор, пока не появится реальный объект для работы и работает правильно.

(и большое спасибо пользователям, которые опубликовали это решение, он решил главную проблему для меня)

+0

Хотя для людей достаточно подкласса 'SurfaceView' и он реализует' SurfaceHolder.Callback', это не требуется; выполнение этого в 'surfaceCreated' является только вариантом, если их класс реализует его. Что касается связанного примечания, то какие обстоятельства вызовут 'setWillNotDraw (false)' в конструкторе причиной сбоя? –

7

Romain Guy explained это:

Для повышения эффективности, макеты не получают их метод onDraw() под названием , Чтобы включить его, вызовите setWillNotDrawEnabled(false) (или установить эквивалентный атрибут XML в ложь.)

+0

Что такое эквивалент атрибута XML? –

2

Основываясь на всех вышеизложенных замечаний, которые я использовал:

Добавить setWillNotDraw (ложь) в случае onAttachedToWindow().

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

, и она работала.

Смежные вопросы