Android:FingerPaint橡皮擦功能
我正在尝试在Android的Api演示中的Fingerpaint应用程序上实现擦除功能。我会根据自己的需要修改一些代码。起初,擦除功能运行良好。我用过:Android:FingerPaint橡皮擦功能,android,path,paint,erase,Android,Path,Paint,Erase,我正在尝试在Android的Api演示中的Fingerpaint应用程序上实现擦除功能。我会根据自己的需要修改一些代码。起初,擦除功能运行良好。我用过: drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 在位图中绘制路径时,它工作良好。但是,当我实现Undo和Redo功能时(我实现它的方法是使用两个arraylist并在那里保存路径),PorterDuffXfermode不起作用。请看一下: 在图1中,
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
在位图中绘制路径时,它工作良好。但是,当我实现Undo和Redo功能时(我实现它的方法是使用两个arraylist并在那里保存路径),PorterDuffXfermode不起作用。请看一下:
在图1中,我绘制了一些路径(存储在arraylist中,而不是在位图画布中绘制)
然后在2点,我按下了擦除图标。我不知道是什么原因导致所有的路都变黑了。然后在3点,我试图抹去我所做的路径(有人说它是黑色的)。然后当我切换回绘图模式。似乎它所做的只是画出另一条路,而不是抹去或抹去
有什么解决办法吗?还是变通办法?
下面是我的drawingClass的代码:
//this is where the drawing takes place
public class DrawingClass extends View{
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
private float brushSize,lastBrushSize;
private boolean erase = false;
//array list for paths
private ArrayList<PathPoints> paths = new ArrayList<PathPoints>();
private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>();
public Context context;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
public DrawingClass(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
this.context = context;
setupDrawing();
}
private void setupDrawing(){
setFocusable(true);
setFocusableInTouchMode(true);
//instantiate the variable to get the last brush size
brushSize = getResources().getInteger(R.integer.medium_size);
lastBrushSize = brushSize;
//get drawing area setup for interaction
drawCanvas = new Canvas();
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
//initial properties
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
//paths.add(new PathPoints(drawPath, paintColor, brushSize));
}
public void setBrushSize(float newSize){
//update brush size
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize = pixelAmount;
drawPaint.setStrokeWidth(brushSize);
invalidate();
}
public void setLastBrushSize(float lastSize){
//set the last brush size
lastBrushSize = lastSize;
invalidate();
}
public float getLastBrushSize(){
//return the last brush size
return lastBrushSize;
}
public void setErase(boolean isErase){
//set erase true or false
erase = isErase;
if (erase) {
//drawPaint.setColor(Color.WHITE);
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
else drawPaint.setXfermode(null);
}
public void startNew(){
//creates a new canvass
drawCanvas.drawColor(0,PorterDuff.Mode.CLEAR);
drawCanvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
setDrawingCacheEnabled(true);
String imgSaved = MediaStore.Images.Media.insertImage(
context.getContentResolver(), getDrawingCache(),
UUID.randomUUID().toString()+".png", "drawing");
destroyDrawingCache();
paths.clear();
undonePaths.clear();
invalidate();
}
@Override
protected void onSizeChanged(int w,int h,int oldw,int oldh){
//view given size
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
@Override
protected void onDraw(Canvas canvas){
//draw view
//save the strokes in the bitmap
//canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
for (PathPoints p : paths){
drawPaint.setColor(p.getColor());
drawPaint.setStrokeWidth(p.getBrush());
invalidate();
canvas.drawPath(p.getPath(), drawPaint);
}
}
private void touch_start(float x, float y){
drawPath.reset();
drawPath.moveTo(x, (float) (y+.1));
drawPath.lineTo(x, y);
drawPath.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) {
drawPath.quadTo(mX, mY, (x + mX)/2, (y+ mY)/2);
mX = x;
mY = y;
}
}
private void touch_up(){
drawPath.lineTo(mX, mY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath = new Path();
paths.add(new PathPoints(drawPath, paintColor, brushSize));
}
@Override
public boolean onTouchEvent(MotionEvent event){
//detect user touch
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
invalidate();
touch_start(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
invalidate();
touch_move(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
invalidate();
touch_up();
drawPath.reset();
break;
default:
return false;
}
invalidate();
return true;
}
public void undoPath(){
if (paths.size()>0) {
undonePaths.add(paths.remove(paths.size()-1));
} else {
Log.d("Undo", "No paths left");
}
invalidate();
}
public void redoPath(){
if (undonePaths.size()>0) {
paths.add(undonePaths.remove(undonePaths.size()-1));
} else {
Log.d("Redo", "No paths left");
}
invalidate();
}
public void setColor(String newColor){
//set color
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
invalidate();
}
class PathPoints{
private Path path;
private int color;
private float brushsize;
private int x, y;
//holds the paths data
public PathPoints(Path path, int color, float brushsize) {
this.path = path;
this.color = color;
this.brushsize = brushsize;
}
public Path getPath() {
return path;
}
public void setPath(Path path) {
this.path = path;
}
public float getBrush(){
return brushsize;
}
public void setBrush(float brushsize){
this.brushsize = brushsize;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
}
//这是绘图的地方
公共类DrawingClass扩展视图{
//绘图路径
专用路径;
//绘画和油画
私人油漆拉丝漆、帆布漆;
//原色
私有int paintColor=0xFF660000;
//帆布
私人帆布;
//画布位图
私有位图画布位图;
私人浮动笔刷大小,lastBrushSize;
私有布尔擦除=假;
//路径的数组列表
私有ArrayList路径=新ArrayList();
private ArrayList undonePaths=new ArrayList();
公共语境;
私人浮动mX,我的;
专用静态最终浮动接触公差=4;
公共绘图类(上下文、属性集属性){
超级(上下文,attrs);
//TODO自动生成的构造函数存根
this.context=上下文;
设置绘图();
}
专用图纸(){
设置聚焦(真);
setFocusableInTouchMode(真);
//实例化变量以获取最后一个笔刷大小
brushSize=getResources().getInteger(R.integer.medium\u size);
lastBrushSize=笔刷大小;
//获取用于交互的绘图区域设置
drawCanvas=新画布();
drawPath=新路径();
drawPaint=新油漆();
drawPaint.setColor(paintColor);
//初始属性
drawPaint.setAntiAlias(真);
drawPaint.设置行程宽度(刷号);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(绘制.连接.圆形);
drawPaint.setStrokeCap(油漆盖圆形);
画布绘制=新绘制(绘制抖动标志);
//添加(新路径点(drawPath、paintColor、brushSize));
}
公共大小(浮动新闻大小){
//更新笔刷大小
浮点像素数量=类型值。应用尺寸(类型值。复杂单位),
newSize,getResources().getDisplayMetrics());
笔刷大小=像素数量;
drawPaint.设置行程宽度(刷号);
使无效();
}
公共空白setLastBrushSize(浮动lastSize){
//设置最后一个笔刷大小
lastBrushSize=lastSize;
使无效();
}
公共浮点getLastBrushSize(){
//返回最后一个笔刷大小
返回最后一个笔刷大小;
}
公共void setErase(布尔isErase){
//将擦除设置为真或假
擦除=iSeries;
如果(删除){
//drawPaint.setColor(颜色:白色);
setXfermode(新的PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
else drawPaint.setXfermode(null);
}
公共无效startNew(){
//创建新画布
drawCanvas.drawColor(0,PorterDuff.Mode.CLEAR);
drawCanvas.drawBitmap(canvasBitmap,0,0,canvasPaint);
setDrawingCacheEnabled(真);
字符串imgSaved=MediaStore.Images.Media.insertImage(
context.getContentResolver(),getDrawingCache(),
UUID.randomUUID().toString()+“.png”,“drawing”);
销毁DrawingCache();
清除路径();
撤销海王星。清除();
使无效();
}
@凌驾
已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh){
//查看给定的大小
super.onSizeChanged(w,h,oldw,oldh);
canvasBitmap=Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas=新画布(画布位图);
}
@凌驾
受保护的void onDraw(画布){
//绘图视图
//在位图中保存笔划
//drawBitmap(canvasBitmap,0,0,canvasPaint);
对于(路径点p:路径){
setColor(p.getColor());
drawPaint.setStrokeWidth(p.getBrush());
使无效();
drawPath(p.getPath(),drawPaint);
}
}
专用无效触摸启动(浮动x、浮动y){
drawPath.reset();
移动到(x,(浮动)(y+1));
绘制路径。线条到(x,y);
绘制路径。移动到(x,y);
mX=x;
mY=y;
}
私有无效触摸移动(浮动x、浮动y){
float dx=Math.abs(x-mX);
float dy=Math.abs(y-mY);
如果(dx>=接触公差| | dy>=接触公差){
drawPath.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);
mX=x;
mY=y;
}
}
私人空间修补(){
drawPath.lineTo(mX,mY);
drawCanvas.drawPath(drawPath,drawPaint);
drawPath=新路径();
添加(新路径点(drawPath、paintColor、brushSize));
}
@凌驾
公共布尔onTouchEvent(运动事件){
//检测用户触摸
float touchX=event.getX();
float touchY=event.getY();
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
使无效();
触摸启动(触摸X,触摸Y);
打破
case MotionEvent.ACTION\u移动:
使无效();
触摸移动(触摸X,触摸Y);
打破
case MotionEvent.ACTION\u UP:
使无效();
润色;
drawPath.reset();
打破
违约:
返回false;
}
使无效();
返回true;
}
公共路径(){
if(path.size()>0){
undonePaths.add(path.remove(path.size()-1));
}否则{
Log.d(“撤消”,“没有剩余路径”);
}
使无效();
}
公共路径(){
如果(撤消路径大小()>0){
add(undonePaths.remove(undonePaths.size()-1));
}否则{
Log.d(“重做”,“没有剩余路径”);
}
使无效();
}
公众的