从未调用Extended SurfaceView的onDraw()方法

Gab*_*yer 33 android

我正在尝试修改我用于进行相机预览的SurfaceView,以显示重叠的方块.但是,从不调用扩展SurfaceView的onDraw方法.

这是来源:

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();   
    }


}
Run Code Online (Sandbox Code Playgroud)

Gab*_*yer 77

在android-developers Google群组上找到它.你只需要添加:

setWillNotDraw(false)
Run Code Online (Sandbox Code Playgroud)

到构造函数.现在,如果有人能解释我为什么,那将非常感激.

  • 我认为SurfaceView默认将setWillNotDraw设置为false,因为它实际上是要从另一个线程更新(使用getHolder().lockCanvas()).在onDraw中添加额外的绘图效率很低.如果你只需要onDraw,你可以直接从android.view.View派生 (9认同)

小智 22

小修正:

将setWillNotDraw(false)添加到构造函数将导致崩溃,因为尚未创建基础Surface对象.

而是将setWillNotDraw(false)语句放入surfaceCreated()方法中.这会延迟通话,直到有一个真正的对象可以使用,并且正常工作.

(非常感谢发布此解决方案的用户,它解决了我的一个主要问题)


Hos*_*com 7

罗曼盖伊解释说:

为了提高效率,布局不会onDraw()调用它们的方法.要启用它,请调用setWillNotDrawEnabled(false)(或将等效的XML属性设置为false.)


M.H*_*fny 5

根据我使用的上述所有评论:

在 onAttachedToWindow() 事件中添加 setWillNotDraw(false) 。

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

它起作用了。