Extended SurfaceView's onDraw() method never called
I'm trying to modify the SurfaceView I use for doing a camera preview in order to display an overlaying square. However, the onDraw method of the extended SurfaceView is never called.
Here is the source :
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();
}
}
Found it on the android-developers Google group. You simply have to add :
setWillNotDraw(false)
To the constructor. Now if someone could explain me why, that would be greatly appreciated.
Minor correction:
Adding setWillNotDraw(false) to the constructor will cause crashes, because the underlying Surface object is not created yet.
Instead, put the setWillNotDraw(false) statement into the surfaceCreated() method. This delays the call until there's a real object to work with, and works properly.
(and many thanks to the users who posted this solution, it solved a major problem for me)
Romain Guy explained it:
For efficiency, layouts do not get their
onDraw()
method called. To enable it, callsetWillNotDrawEnabled(false)
(or set the equivalent XML attribute to false.)
Based on all above comments I used :
Add setWillNotDraw(false) in the onAttachedToWindow() event.
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setWillNotDraw(false);
}
and it worked.
精彩评论