Android 从未调用过扩展 SurfaceView 的 onDraw() 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2687015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:56:48  来源:igfitidea点击:

Extended SurfaceView's onDraw() method never called

android

提问by Gab Royer

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.

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

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


}

回答by Gab Royer

Found it on the android-developers Google group. You simply have to add :

在 android-developers Google group 上找到它。您只需添加:

setWillNotDraw(false)

To the constructor. Now if someone could explain me why, that would be greatly appreciated.

给构造函数。现在,如果有人能解释我为什么,那将不胜感激。

回答by dreambig

Minor correction:

小修正:

Adding setWillNotDraw(false) to the constructorwill cause crashes, because the underlying Surface object is not created yet.

将 setWillNotDraw(false) 添加到构造函数会导致崩溃,因为尚未创建底层 Surface 对象。

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.

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

(and many thanks to the users who posted this solution, it solved a major problem for me)

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

回答by HostedMetrics.com

Romain Guy explainedit:

罗曼盖伊解释说:

For efficiency, layouts do not get their onDraw()method called. To enable it, call setWillNotDrawEnabled(false)(or set the equivalent XML attribute to false.)

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

回答by M.Hefny

Based on all above comments I used :

基于我使用的所有上述评论:

Add setWillNotDraw(false) in the onAttachedToWindow() event.

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

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

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

and it worked.

它奏效了。