public class MusiceView extends View { Paint mPaint; public MusiceView(Context context) { super(context); mPaint = new Paint();
mPaint.setColor(getResources().getColor(android.R.color.holo_blue_dark));
mPaint.setStrokeWidth(20); } public MusiceView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public MusiceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { canvas.drawLine(0,0,0,100,mPaint); } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.superdy.test.MainActivity"> <com.example.superdy.test.MusiceView android:layout_centerInParent="true" android:layout_width="100dp" android:layout_height="100dp" /> </RelativeLayout>
报错
java.lang.NullPointerException: Attempt to invoke virtual method 'long
android.graphics.Paint.getNativeInstance()' on a null object reference
为什么
我们翻开源码看看注释
/** * Simple constructor to use when creating a view from code. * * @param context The Context the view is running in, through which it can * access the current theme, resources, etc. */ public View(Context context) {。。。
/** * Constructor that is called when inflating a view from XML. This is called * when a view is being constructed from an XML file, supplying attributes * that were specified in the XML file. This version uses a default style of * 0, so the only attribute values applied are those in the Context's Theme * and the given AttributeSet. * * <p> * The method onFinishInflate() will be called after all children have been * added. * * @param context The Context the view is running in, through which it can * access the current theme, resources, etc. * @param attrs The attributes of the XML tag that is inflating the view. * @see #View(Context, AttributeSet, int) */ public View(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); }
===========================
原因明了了
第一个构造方法时在代码中创建view的时候可以使用的
而第二个构造方法则是在xml中创建view的时候使用的。
我们修改下代码
public class MusiceView extends View { Paint mPaint; public MusiceView(Context context) { super(context); } public MusiceView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); mPaint.setColor(getResources().getColor(android.R.color.holo_blue_dark)); mPaint.setStrokeWidth(20); } public MusiceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { canvas.drawLine(0,0,0,100,mPaint); } }
这次成功了,画出了一条线段。