我尝试将自己的DrawingView extends View
创建为名为AddCanvasActivity
,他们分享了许多争论并相互影响,所以我认为这是一个好主意。
我遇到的问题: 我想
setContentView(R.layout.view_add_canvas);
进入该活动的OnCreate
,但我收到以下错误消息
FATAL EXCEPTION: main
Process: com.graphicuss.graphicuss, PID: 3934
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.graphicuss.graphicuss/com.graphicuss.graphicuss.AddCanvasActivity}: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class com.graphicuss.graphicuss.AddCanvasActivity.DrawingView
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class com.graphicuss.graphicuss.AddCanvasActivity.DrawingView
Caused by: android.view.InflateException: Binary XML file line #0: Error inflating class com.graphicuss.graphicuss.AddCanvasActivity.DrawingView
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.graphicuss.graphicuss.AddCanvasActivity.DrawingView" on path: DexPathList[[zip file "/data/app/com.graphicuss.graphicuss-1/base.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.graphicuss.graphicuss-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.graphicuss.graphicuss-1/lib/x86, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
依此类推,因为我尝试setContentView.
在我的XML中
view_add_canvas
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:paddingLeft="16dp"
android:paddingRight="16dp"
tools:context=".AddCanvasActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:minHeight="100dp"
android:minWidth="400dp" />
<com.graphicuss.graphicuss.AddCanvasActivity.DrawingView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/DrawingViewAddCanvas"
class="com.graphicuss.graphicuss.AddCanvasActivity.DrawingView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="Hier Zeichnen" />
</LinearLayout>
</RelativeLayout>
...在那里我想加载DrawingView
元素,它在我提到的Activity中定义。
无论如何我是否必须将它添加到Manifest中?
更新#1:
整个ShowAllActivity
包括DrawingView
public class DrawingView extends View {
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
private Path mPreviewPath;
private ShapeDrawable mDrawable;
private float mStartX;
private float mStartY;
private float mDistanceX;
private float mDistanceY;
private float mDistance;
private float radiusPreview;
private Paint clearPaint;
public DrawingView(Context c) {
super(c);
Log.d("ADDCANVAS - DrawingView", "OnCreate1");
context = c;
mPath = new Path();
mPreviewPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
clearPaint = new Paint();
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
clearPaint.setColor(Color.WHITE);
}
public DrawingView(Context c, AttributeSet attributeSet) {
super(c,attributeSet);
Log.d("ADDCANVAS - DrawingView", "OnCreate2");
context = c;
mPath = new Path();
mPreviewPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
clearPaint = new Paint();
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
clearPaint.setColor(Color.WHITE);
}
public DrawingView(Context c, AttributeSet attributeSet, int defStyle) {
super(c,attributeSet,defStyle);
Log.d("ADDCANVAS - DrawingView", "OnCreate3");
context = c;
mPath = new Path();
mPreviewPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
clearPaint = new Paint();
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
clearPaint.setColor(Color.WHITE);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d("ADDCANVAS- DrawingView", "OnSizeChanged");
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
if(!mFinished) {
Log.d("ADDCANVAS- DrawingView", "OnDraw");
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
if (mDrawOption == "pencil" || mDrawOption == "line") canvas.drawPath(mPath, mPaint);
canvas.drawPath(circlePath, circlePaint);
canvas.drawPath(mPreviewPath, mPaint);
}
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
Log.d("ADDCANVAS- DrawingView", "TouchStart");
mStartX = x;
mStartY = y;
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
Log.d("ADDCANVAS- DrawingView", "TouchMove");
float dx = abs(x - mX);
float dy = abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mDistanceX = abs(x - mStartX);
mDistanceY = abs(y - mStartY);
mDistance = (float) sqrt((mDistanceX * mDistanceX) + (mDistanceY * mDistanceY));
mPreviewPath.reset();
switch (mDrawOption) {
case "circle":
mPreviewPath.addCircle(mStartX, mStartY, mDistance, Path.Direction.CW);
break;
case "pencil":
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
break;
case "ellipse":
mPreviewPath.addOval(mStartX, mStartY, x, y, Path.Direction.CW);
break;
case "line":
mPreviewPath.moveTo(mStartX, mStartY);
mPreviewPath.quadTo(mStartX, mStartY, x, y);
break;
case "rectangle":
if (mStartX > x) {
if (mStartY > y) {
mPreviewPath.addRect(x, y, mStartX, mStartY, Path.Direction.CW);
} else mPreviewPath.addRect(x, mStartY, mStartX, y, Path.Direction.CW);
}
if (mStartY > y) {
mPreviewPath.addRect(mStartX, y, x, mStartY, Path.Direction.CW);
}
mPreviewPath.addRect(mStartX, mStartY, x, y, Path.Direction.CW);
break;
case "text":
//to be done
break;
default:
break;
}
mX = x;
mY = y;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up(float x, float y) {
Log.d("ADDCANVAS- DrawingView", "TouchUp");
mPath.lineTo(mX, mY);
mDistanceX = abs(x - mStartX);
mDistanceY = abs(y - mStartY);
mDistance = (float) sqrt((mDistanceX * mDistanceX) + (mDistanceY * mDistanceY));
Path pa = new Path();
Log.d("DrawOption: State", mDrawOption);
switch (mDrawOption) {
case "circle":
mCanvas.drawCircle(mStartX, mStartY, mDistance, mPaint);
pa.addCircle(mStartX,mStartY,mDistance,Path.Direction.CW);
Log.d("DrawOption", "Circle, Touch up");
Log.d("DrawOption: Dist", Float.toString(mDistance));
Log.d("DrawOption: DistX", Float.toString(mDistanceX));
Log.d("DrawOption: DistY", Float.toString(mDistanceY));
Log.d("DrawOption: mX", Float.toString(mX));
Log.d("DrawOption: mX", Float.toString(mY));
break;
case "rectangle":
mCanvas.drawRect(mStartX, mStartY, x, y, mPaint);
if (mStartX > x) {
if (mStartY > y) {
pa.addRect(x, y, mStartX, mStartY, Path.Direction.CW);
} else pa.addRect(x, mStartY, mStartX, y, Path.Direction.CW);
}
if (mStartY > y) {
pa.addRect(mStartX, y, x, mStartY, Path.Direction.CW);
}
pa.addRect(mStartX, mStartY, x, y, Path.Direction.CW);
break;
case "ellipse":
mCanvas.drawOval(mStartX, mStartY, x, y, mPaint);
pa.addOval(mStartX,mStartY,x,y,Path.Direction.CW);
break;
case "line":
mCanvas.drawLine(mStartX, mStartY, x, y, mPaint);
break;
case "text":
mCanvas.drawText("Text", mX, mY, mPaint);
break;
case "pencil":
mCanvas.drawPath(mPath, mPaint);
pa.addPath(mPath);
break;
default:
Log.d("DrawOption: default", mDrawOption);
}
PathInformation pi = new PathInformation(pa, true, mPaint);
Log.d("before add path color", Integer.toString(mPaint.getColor()));
mPathsArray.addPath(pi);
circlePath.reset();
mPreviewPath.reset();
// commit the path to our offscreen
// mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(!mFinished) {
Log.d("ADDCANVAS- DrawingView", "onTouchEvent");
Log.d("TouchEvent true", Float.toString(event.getX()));
Log.d("TouchEvent true", Float.toString(event.getY()));
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up(x, y);
invalidate();
break;
}
return true;
}
else {
Log.d("TouchEvent false", Float.toString(event.getX()));
Log.d("TouchEvent false", Float.toString(event.getY()));
return false;
}
}
public void undoLastPath() {
boolean b = mPathsArray.undoLast();
if(b) {
mCanvas.drawRect(0, 0, mCanvas.getWidth(), mCanvas.getHeight(), clearPaint);
invalidate();
for (int i = 0; i <= mPathsArray.getLength(); i++) {
if (mPathsArray.getPathInfo(i).getValid() == true) {
mCanvas.drawPath(mPathsArray.getPathInfo(i).getPath(), mPathsArray.getPathInfo(i).getPaint());
Log.d("Undolastpath paint", Integer.toString(mPathsArray.getPathInfo(i).getPaint().getColor()));
}
}
invalidate();
}
}
}