我正在开发一个绘图应用程序,但面临一些撤消问题。编码如下:
public class DoodleView extends View
{
Context context_new;
private static final float TOUCH_TOLERANCE = 5;
private Bitmap bitmap; // drawing area for display or saving
private Canvas bitmapCanvas; // used to draw on bitmap
private Paint paintScreen; // use to draw bitmap onto screen
private Paint paintLine; // used to draw lines onto bitmap
private Path mPath;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
private float mX, mY;
// DoodleView constructor initializes the DoodleView
public DoodleView(Context context, AttributeSet attrs)
{
super(context, attrs); // pass context to View's constructor
this.context_new=context;
paintScreen = new Paint(); // used to display bitmap onto screen
// set the initial display settings for the painted line
paintLine = new Paint();
paintLine.setAntiAlias(true); // smooth edges of drawn line
paintLine.setColor(Color.BLACK); // default color is black
paintLine.setStyle(Paint.Style.STROKE); // solid line
mPath = new Path();
paths.add(mPath);
} // end DoodleView constructor
OnSizeChanged:
@Override
public void onSizeChanged(int w, int h, int oldW, int oldH)
{
super.onSizeChanged(w, h, oldW, oldH);
DoodlzViewWidth = w;
DoodlzViewHeight = h;
bitmap = Bitmap.createBitmap(getWidth(), DoodlzViewHeight, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas(bitmap);
bitmap.eraseColor(Color.WHITE); // erase the BitMap with white
}
onDraw:
@Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, paintScreen);
// for each path currently being drawn
for (Path p : paths){canvas.drawPath(p, paintLine);}
}
的onTouchEvent:
@Override
public boolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
touchStarted(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMoved(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchEnded();
invalidate();
break;
}
return true;
}
touchStarted:
private void touchStarted(float x, float y)
{
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
touchMoved:
private void touchMoved(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;
}
}
touchEnded:
private void touchEnded()
{
mPath.lineTo(mX, mY);
bitmapCanvas.drawPath(mPath, paintLine);
mPath = new Path();
paths.add(mPath);
Toast.makeText(getContext(), "touchEnded" + paths.size(), Toast.LENGTH_SHORT).show();
}
撤消:
public void onClickUndo()
{
Toast.makeText(getContext(), "before undo button pressed " + paths.size(), Toast.LENGTH_SHORT).show();
if (paths.size()>0)
{
undonePaths.add(paths.remove(paths.size()-1));
Toast.makeText(getContext(), "after undo button pressed " + paths.size(), Toast.LENGTH_SHORT).show();
Log.i("UNDOING", "PREPARE INVALIDATE");
invalidate();
Log.i("UNDOING", "FINISH INVALIDATE");
}
else Toast.makeText(getContext(), "nothing to undo" + paths.size(), Toast.LENGTH_SHORT).show();
}
以上内容源自在线搜索的其他示例。不知道为什么在实现touchStarted
时需要设置path.reset()?
Q1。当我按下撤消按钮时,它会正确显示按下toast
撤消按钮,并报告path.size()
为0,因此之前绘制的行未删除 。我真的不知道为什么它是0?它已经添加到路径数组了吗?如何修改代码?
**代码修改后采取android-developer的建议!谢谢!!它现在正确显示path.size()。对不起傻丢错了!* 但是之前画的线还是无法删除? =(
Q2。当手指在屏幕上移动并立即显示线条时,应用程序正常运行,当我按下撤消按钮时,除了上面没有删除前一行之外,线条在按下之后进一步绘制到屏幕在手指抬起之前,按钮不会显示。
回答Q2:
将以下2行从touchEnded()
移至touchStarted()
mPath = new Path();
paths.add(mPath);
private void touchStarted(float x, float y)
{
mPath.reset();
mPath = new Path();
paths.add(mPath);
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touchEnded()
{
mPath.lineTo(mX, mY);
bitmapCanvas.drawPath(mPath, paintLine);// commit the path to our offscreen
Toast.makeText(getContext(), "touchEnded" + paths.size(), Toast.LENGTH_SHORT).show();
}
感谢!!!
答案 0 :(得分:4)
不会放置canvas.drawBitmap(bitmap, 0, 0, paintScreen);
或canvas.drawBitmap(bitmap, 0, 0, paintLine);
private Bitmap bitmap; // drawing area for display or saving
private Canvas bitmapCanvas; // used to draw on bitmap
private Paint paintLine; // used to draw lines onto bitmap
private Path mPath;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
// DoodleView constructor initializes the DoodleView
public DoodleView(Context context, AttributeSet attrs)
{
super(context, attrs); // pass context to View's constructor
this.context_new=context;
setFocusable(true);
setFocusableInTouchMode(true);
// set the initial display settings for the painted line
paintLine = new Paint();
paintLine.setAntiAlias(true); // smooth edges of drawn line
paintLine.setDither(true);
paintLine.setColor(Color.BLACK); // default color is black
paintLine.setStyle(Paint.Style.STROKE); // solid line
paintLine.setStrokeJoin(Paint.Join.ROUND);
paintLine.setStrokeWidth(5); // set the default line width
paintLine.setStrokeCap(Paint.Cap.ROUND); // rounded line ends
bitmapCanvas = new Canvas();
mPath = new Path();
} // end DoodleView constructor
// Method onSizeChanged creates BitMap and Canvas after app displays
@Override
public void onSizeChanged(int w, int h, int oldW, int oldH)
{
super.onSizeChanged(w, h, oldW, oldH);
DoodlzViewWidth = w;
DoodlzViewHeight = h;
}
@Override
protected void onDraw(Canvas canvas)
{
for (Path p : paths){canvas.drawPath(p, paintLine);}
canvas.drawPath(mPath, paintLine);
Log.i("OnDRAWING", "REACH ON DRAW");
}
// START TOUCH:处理触摸事件 @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);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
private void touch_start(float x, float y)
{
undonePaths.clear();
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);
bitmapCanvas.drawPath(mPath, paintLine);// commit the path to our offscreen
paths.add(mPath);
mPath = new Path();
}
public void onClickUndo()
{
if (paths.size()>0)
{
undonePaths.add(paths.remove(paths.size()-1));
invalidate();
}
else Toast.makeText(getContext(), "nothing more to undo", Toast.LENGTH_SHORT).show();
}