使用"id"替代"android:id"引发NullPointerException及自定义TriangleDrawView问题
id而非android:id导致的NullPointerException问题 嘿,这个问题我太熟了!咱们先把核心原因说清楚:当你在布局里用id而不是android:id给View设置标识时,会直接导致findViewById()返回null,进而触发NullPointerException。
为什么会这样?
Android的资源系统只认带android:命名空间的id属性——只有用android:id="@+id/xxx",编译时APT(注解处理工具)才会把这个id写入R.java文件里,让你的代码能通过findViewById()找到对应的View。要是只写id="@+id/xxx",这个属性完全不会被系统处理,相当于你的View没被分配有效的资源ID,找当然找不到啦。
结合你的自定义View来修正
回到你写的TriangleDrawView,假设你在布局里是这么引用它的,那肯定会踩坑:
<com.yourpackage.TriangleDrawView
id="@+id/my_triangle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
必须改成带android:前缀的标准写法:
<com.yourpackage.TriangleDrawView
android:id="@+id/my_triangle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
格式化后的自定义View代码(补充了必要初始化逻辑)
你原来的代码我帮你整理好了,还补了构造方法和初始化逻辑,方便你直接用:
import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.support.annotation.Nullable; import android.support.v4.content.res.ResourcesCompat; import android.util.AttributeSet; import android.view.View; public class TriangleDrawView extends View { private Paint mPaint; private Path mPath; // 必须实现的三个构造方法,确保布局系统能正确实例化View public TriangleDrawView(Context context) { super(context); init(); } public TriangleDrawView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public TriangleDrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } // 统一初始化绘制资源的方法 private void init() { // 初始化画笔,开启抗锯齿 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(ResourcesCompat.getColor(getResources(), R.color.black, null)); mPaint.setStyle(Paint.Style.FILL); // 初始化路径 mPath = new Path(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制三角形的逻辑 mPath.reset(); mPath.moveTo(getWidth() / 2, 0); mPath.lineTo(0, getHeight()); mPath.lineTo(getWidth(), getHeight()); mPath.close(); canvas.drawPath(mPath, mPaint); } }
内容的提问来源于stack exchange,提问作者Tharindu Sathischandra

