2

我正在创建一个添加到 FrameLayout 的自定义视图。当我初始化视图时,我得到一个 NullPointerException。我究竟做错了什么。视图的代码是:

public class DocumentCameraMask extends View {

    private Context mContext;

    public DocumentCameraMask(Context context) {
        super(context);

        this.mContext = context;
    }

    @Override
    public void draw(Canvas canvas) {
        // TODO Auto-generated method stub

        Paint paint = new Paint();
        paint.setColor(this.mContext.getResources().getColor(R.color.textColor));
        paint.setStyle(Paint.Style.STROKE);

        Rect cropRect = new Rect(0,0,800,600);
        canvas.drawRect(cropRect, paint);

        super.draw(canvas);

    }

}

cropRect 大小将动态计算,这就是我需要制作此视图的原因。谢谢你的帮助。

日志猫

09-11 19:13:04.590:E/AndroidRuntime(4235):致命异常:主要 09-11 19:13:04.590:E/AndroidRuntime(4235):java.lang.RuntimeException:无法启动活动 DocumentCameraActivity}:java .lang.NullPointerException 09-11 19:13:04.590: E/AndroidRuntime(4235): 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) 09-11 19:13:04.590: E/AndroidRuntime(4235) : 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2211) 09-11 19:13:04.590: E/AndroidRuntime(4235): 在 android.app.ActivityThread.access$600(ActivityThread.java:149) 09- 11 19:13:04.590: E/AndroidRuntime(4235): 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1300) 09-11 19:13:04.590: E/AndroidRuntime(4235): 在 android. os.Handler.dispatchMessage(Handler.java:99) 09-11 19:13:04.590:E/AndroidRuntime(4235): 在 android.os.Looper.loop(Looper.java:153) 09-11 19:13:04.590: E/AndroidRuntime(4235): 在 android.app.ActivityThread.main(ActivityThread.java :4987) 09-11 19:13:04.590: E/AndroidRuntime(4235): 在 java.lang.reflect.Method.invokeNative(Native Method) 09-11 19:13:04.590: E/AndroidRuntime(4235): 在java.lang.reflect.Method.invoke(Method.java:511) 09-11 19:13:04.590: E/AndroidRuntime(4235): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java :821) 09-11 19:13:04.590: E/AndroidRuntime(4235): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584) 09-11 19:13:04.590: E/AndroidRuntime (4235): 在 dalvik.system.NativeStart.main(Native Method) 09-11 19:13:04.590: E/AndroidRuntime(4235): 由: java.lang.NullPointerException 09-11 19:13:04.590:E/AndroidRuntime(4235): 在 android.view.ViewConfiguration.get(ViewConfiguration.java:332) 09-11 19:13:04.590: E/AndroidRuntime(4235): 在 android.view.View.(View.java:第3243章

4

3 回答 3

5

您不必重写draw()方法View,无论您想做什么绘图,都可以使用onDraw()方法。

public class DocumentCameraMask extends View {

        private Context mContext;

        public DocumentCameraMask(Context context) {
            super(context);

            this.mContext = context;
        }

        @Override
        public void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
            Paint paint = new Paint();
            paint.setColor(this.mContext.getResources().getColor(R.color.textColor));
            paint.setStyle(Paint.Style.STROKE);

            Rect cropRect = new Rect(0,0,800,600);
            canvas.drawRect(cropRect, paint);             

        }

    }

参考文献:

1. 谷歌链接

2.另一个链接,这可能对你有帮助

更新:

我的主要活动:

public class MainActivity extends Activity {
DocumentCameraMask mask;
    RelativeLayout rel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rel = (RelativeLayout) findViewById(R.id.t);
mask = new DocumentCameraMask(this);

        mask.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT));
        byte b = 100;
        int a = b;
        Toast.makeText(this,"Int "+a,Toast.LENGTH_LONG).show();

rel.addView(mask);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

自定义视图 DocumentCameraMask 类:

public class DocumentCameraMask extends View {

        private Context mContext;

        public DocumentCameraMask(Context context) {
            super(context);

            this.mContext = context;
        }

        @Override
        public void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
            Paint paint = new Paint();
            paint.setColor(Color.BLUE);
            paint.setStyle(Paint.Style.STROKE);

            Rect cropRect = new Rect(0,0,800,600);
            canvas.drawRect(cropRect, paint);             

        }

    }

输出:

在此处输入图像描述

于 2013-09-11T15:11:05.827 回答
1

您需要添加另一个构造函数。特别是,如果您View在 XML 文件中使用它,它会使用不同的构造函数,而您没有提供该构造函数。

a 的三个构造函数View是:

View(Context context, AttributeSet attrs, int defStyle)

View(Context context, AttributeSet attrs)

View(Context context)

至少,您应该覆盖第二个,因为这是从 XML 文件中最常调用的内容。只要确保你打电话给super()每个人的匹配。


笔记:

正如格鲁所说,你真的应该压倒一切onDraw(),而不是draw()。我不知道你的 Eclipse 告诉你什么,但我从来不需要覆盖draw(),也从来没有建议我这样做。

于 2013-09-11T15:36:17.923 回答
1

您可以尝试以下操作:

public class DocumentCameraMask extends View {

    private Context mContext;

    /*
    If you ever want to include custom-view manually in code without any layout      attributes,use this constructor.
    */ 

    public DocumentCameraMask(Context context) {
        this(context,null);       
    }

    /*
      If you want to include the custom view in a layout XML file, you need to use this 
      constructor. 
    */ 
    public DocumentCameraMask(Context context,AttributeSet attrs) {
        super(context,attrs);
        this.mContext = context;        
    }    


    /*
     If you need to actually do something with the view you have. To do this, you must   override the onDraw method of your custom-View class.
     */

    @Override
    public void onDraw(Canvas canvas) {

        /*
          If you want to call the superclass onDraw method (eg.TextView rather than a generic View), then call super.onDraw().If you don't want that, i.e. you are planning to draw the entire View yourself ,there's no reason to call it. If you look at the source code, it shows that View.onDraw() is an empty method. So, calling super.onDraw(), if the parent class is View itself, does nothing. 
         */

        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setColor(mContext.getResources().getColor(R.color.textColor));
        paint.setStyle(Paint.Style.STROKE);

        Rect cropRect = new Rect(0,0,800,600);
        canvas.drawRect(cropRect, paint);
    }      
}

您可以参考自定义图纸

注意:根据文档,

  1. 公共无效绘制(画布画布)

在 API 级别 1 中添加

Manually render this view (and all of its children) to the given Canvas. 
The view must have already done a full layout before this function is called. 
When implementing a view, implement onDraw(android.graphics.Canvas) 
instead of overriding this method. If you do need to override this method,
call the superclass version.
  2. protected void onDraw (Canvas canvas)

在 API 级别 1 中添加

Implement this to do your drawing.
于 2013-09-11T16:33:52.653 回答