gpt4 book ai didi

android - 在 Android 上创建自定义 View 时在绘制时出现空指针错误?

转载 作者:行者123 更新时间:2023-11-29 17:59:15 25 4
gpt4 key购买 nike

我正在做一个小型绘画 android 应用程序。我想创建一个自定义 View 来在其上绘制一些东西。当创建布局并添加我的 View 时。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.androidpaint.PaintView
android:id="@+id/paintPlace"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</RelativeLayout>

出现错误

java.lang.NullPointerException
Exception details are logged in Window > Show View > Error Log
java.lang.NullPointerException
at android.graphics.Canvas.drawPath(Canvas.java:1021)
at com.example.androidpaint.PaintView.onDraw(PaintView.java:69)
at android.view.View.draw(View.java:13712)
at android.view.View.draw(View.java:13596)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.draw(View.java:13594)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.draw(View.java:13594)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.draw(View.java:13715)
at android.view.View.draw(View.java:13596)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.draw(View.java:13715)

这是我的 PaintView 类:

public class PaintView extends View{
boolean isEraser = false;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private Paint mPaint;
private Paint mPaintScreen;
int color;
public PaintView(Context c) {
super(c);
mPaintScreen = new Paint();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(5);
color = mPaint.getColor();
mPath = new Path();

mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);


}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PaintView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mBitmap.eraseColor(Color.WHITE);
}
private float mX =-100, mY = -100;
Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.background );
private static final float TOUCH_TOLERANCE = 7;

@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap,0,0,mPaintScreen);
canvas.drawPath(mPath, mPaint);
canvas.drawBitmap(b, 10, 10, mPaint);
}
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x -mX);
float dy = Math.abs(y - mY);
if(dx>=TOUCH_TOLERANCE||dy>=TOUCH_TOLERANCE){
mPath.quadTo(mX,mY, (x+mX)/2, (y+mY)/2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
mX =-100;
mY = -100;

}

@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
break;
case MotionEvent.ACTION_UP:
touch_up();
break;
}
postInvalidate();
return true;
}
public void setColor(int c){
if(isEraser)
mPaint.setColor(Color.WHITE);
else{
mPaint.setColor(Color.CYAN);
//mPaint.setColor(c);
color = c;
postInvalidate();
}
}
public float getLineWidth(){
return mPaint.getStrokeWidth();
}
public void setLineWidth(float w){
mPaint.setStrokeWidth(w);
}
public int getDrawingColor(){
return mPaint.getColor();
}
public void clearPaint(){
mPath.reset();
mBitmap.eraseColor(Color.WHITE);
invalidate();
}
public void setEraserIcon(){
b = BitmapFactory.decodeResource(getResources(),R.drawable.eraser );
color = mPaint.getColor();
mPaint.setColor(Color.WHITE);
isEraser = true;
}
public void setBrushIcon(){
b = BitmapFactory.decodeResource(getResources(),R.drawable.brush );
mPaint.setColor(color);
isEraser = false;

}
public void saveImage(){
String fileName = "Image" + System.currentTimeMillis();

ContentValues values = new ContentValues();
values.put(Images.Media.TITLE,fileName);
values.put(Images.Media.DATE_ADDED,System.currentTimeMillis());
values.put(Images.Media.MIME_TYPE,"image/jpeg");

Uri uri = getContext().getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
try{
OutputStream outStream = getContext().getContentResolver().openOutputStream(uri);
mBitmap.compress(Bitmap.CompressFormat.JPEG,100, outStream);
outStream.flush();
outStream.close();

Toast message = Toast.makeText(getContext(), R.string.message_saved, Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER, message.getXOffset(),message.getYOffset());
message.show();

}catch(Exception ex){
Toast message = Toast.makeText(getContext(),R.string.message_error_saving, Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER, message.getXOffset()/2,message.getYOffset()/2);
message.show();
}
}
}`

我创建了一个新的 Activity 并设置了如下代码:

 protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(new PaintView(this));
}

但是当调用我的包含 PaintView 的 XML 时。它得到我上面说的错误

我是 android 的新手,非常感谢你帮助我!

最佳答案

尝试在 public PaintView(Context context, AttributeSet attrs) 构造函数中添加初始化代码。所以它看起来像:

   public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintScreen = new Paint();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(5);
color = mPaint.getColor();
mPath = new Path();

mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}

并且不是调用 setContentView(new PaintView(this)); 而是调用 setContentView(your.xml); 你的 View 在哪里作为标签。

您遇到 NullPointerException 是因为您没有正确初始化您的自定义 View。当您在 XML 文件中创建 View 时,将调用 YourView(Context context, AttributeSet attrs) 构造函数。

当您使用 YourView view = new YourView(this)' - 'YourView(Context context) 动态创建 View 时被调用。

为防止这种情况发生,您可以在内部创建带有初始化的小方法,您将在其中初始化组件,然后从每个构造函数调用此方法。

当您想为绘图动态设置一些其他值时,您需要在每次更改后调用 invalidate();

关于android - 在 Android 上创建自定义 View 时在绘制时出现空指针错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17140478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com