J'ai un programme simple qui dessine l'aperçu du Camera
dans un SurfaceView
. Ce que j'essaie de faire, c’est d’utiliser la méthode onPreviewFrame
, qui est appelée chaque fois qu’un nouveau cadre est dessiné dans le SurfaceView
, afin d’exécuter la méthode invalidate
qui est supposé invoquer la méthode onDraw
. En fait, la méthode onDraw
est invoquée, mais rien n’est en cours d’impression (je suppose que l’aperçu de la caméra remplace le texte que je tente de dessiner).
Ceci est une version simplifiée de la sous-classe SurfaceView
que j'ai:
public class Superficie extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
public Camera camera;
Superficie(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_Push_BUFFERS);
}
public void surfaceCreated(final SurfaceHolder holder) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
invalidar();
}
});
} catch (IOException e) {}
}
public void invalidar(){
invalidate();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
// nothing gets drawn :(
Paint p = new Paint(Color.RED);
canvas.drawText("PREVIEW", canvas.getWidth() / 2,
canvas.getHeight() / 2, p);
}
}
SurfaceView
ne fonctionne probablement pas comme un View
ordinaire à cet égard.
Au lieu de cela, procédez comme suit:
SurfaceView
à l'intérieur d'un FrameLayout
ou RelativeLayout
dans votre fichier XML de présentation, car ces deux éléments permettent d'empiler des widgets sur l'axe des zView
distincte et personnaliséeFrameLayout
ou RelativeLayout
, mais faites-la apparaître après le SurfaceView
.Cela fera apparaître votre classe personnalisée View
comme flottant au-dessus de SurfaceView
.
Voir ici pour un exemple de projet qui superpose les panneaux popup au-dessus d'un SurfaceView
utilisé pour la lecture vidéo.
Essayez d'appeler setWillNotDraw(false)
depuis surfaceCreated
:
public void surfaceCreated(SurfaceHolder holder) {
try {
setWillNotDraw(false);
mycam.setPreviewDisplay(holder);
mycam.startPreview();
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG,"Surface not created");
}
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(area, rectanglePaint);
Log.w(this.getClass().getName(), "On Draw Called");
}
et en appelant invalidate
à partir de onTouchEvent
:
public boolean onTouch(View v, MotionEvent event) {
invalidate();
return true;
}
Je pense que vous devriez d'abord appeler la méthode super.draw()
avant de faire quoi que ce soit dans la méthode draw de surfaceView.