Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在自定义工程视图中,“撤消”和“重做”选项不起作用_Android_Paint_Undo_Undo Redo_Redo - Fatal编程技术网

Android 在自定义工程视图中,“撤消”和“重做”选项不起作用

Android 在自定义工程视图中,“撤消”和“重做”选项不起作用,android,paint,undo,undo-redo,redo,Android,Paint,Undo,Undo Redo,Redo,我正在尝试在自定义工程视图应用程序中设置undo,redo选项。但它并没有像我想要的那样工作 我的英语不好。通过图片,让我试着展示一下undo,redo函数的工作情况。希望如此,这张照片能解释我的问题。 我想在第一次撤消单击时删除第一行,在第二次撤消单击时删除第二行,依此类推。。。同样,在重做时,单击第一次单击绘制最后一行,第二次单击绘制最后一行,依此类推 这是我的自定义视图类 public class DrawingView extends View{ ArrayList<P

我正在尝试在自定义工程视图应用程序中设置
undo
redo
选项。但它并没有像我想要的那样工作

我的英语不好。通过图片,让我试着展示一下
undo
redo
函数的工作情况。希望如此,这张照片能解释我的问题。

我想在第一次撤消单击时删除第一行,在第二次撤消单击时删除第二行,依此类推。。。同样,在重做时,单击第一次单击绘制最后一行,第二次单击绘制最后一行,依此类推

这是我的自定义视图类

public class DrawingView extends View{

    ArrayList<Path> undoPath = new ArrayList<Path>();
    ArrayList<Path> paths    = new ArrayList<Path>();
    private static int pathSize =0;
    //draw path
    private Path drawPath;
    //drawing and canvas point
    private Paint drawPaint, canvasPaint;
    //initial color
    private int paintColor=0xFF660000;
    //canvas
    private Canvas drawCanvas;
    //canvas bitmap
    private Bitmap canvasBitmap;

    private float brushSize, lastBrushSize; 

    public DrawingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setupDrawing();
    }
    public void setPattern(String newPattern){
        invalidate();
        int patternID = getResources().getIdentifier(newPattern, "drawable", "com.faisalahsan.paintingapp");
        Bitmap patternBMP = BitmapFactory.decodeResource(getResources(), patternID);
        BitmapShader patternBMPShader = new BitmapShader(patternBMP, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        drawPaint.setColor(0xFFFFFFFF);
        drawPaint.setShader(patternBMPShader);

    }
    private void setupDrawing(){
        //get drawing area setup for interaction
        drawPath = new Path();
        drawPaint= new Paint();

        paths.add(drawPath);

        brushSize = getResources().getInteger(R.integer.medium_size);
        lastBrushSize = brushSize;

        drawPaint.setColor(paintColor);
        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);     
    }

    @Override
    protected void onDraw(Canvas canvas) {          
        for(Path p: paths){         
            canvas.drawBitmap(canvasBitmap, 0,  0, canvasPaint);
            canvas.drawPath(p, drawPaint);          
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {    
        super.onSizeChanged(w, h, oldw, oldh);
        canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        drawCanvas = new Canvas(canvasBitmap);

    }

    public void onClickUndo () {
        if (paths.size()>0)  {
         undoPath.add(paths.remove(paths.size()-1));         
         invalidate();
        }          
       }

       public void onClickRedo (){
        if (undoPath.size()>0)  {
         paths.add(undoPath.remove(undoPath.size()-1));         
         invalidate();
         }
        }


    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float touchX = event.getX();
        float touchY = event.getY();

        switch (event.getAction()) {
        case  MotionEvent.ACTION_DOWN:
            drawPath.moveTo(touchX, touchY);
            break;          
        case MotionEvent.ACTION_MOVE:
            drawPath.lineTo(touchX, touchY);            
            break;
        case  MotionEvent.ACTION_UP:
            drawCanvas.drawPath(drawPath, drawPaint);
            drawPath.reset();
            drawPath = new Path();
            paths.add(drawPath);
            break;
        default:
            return false;
        }
        invalidate();
        return true;        
    }   
}
公共类DrawingView扩展视图{
ArrayList undoPath=新的ArrayList();
ArrayList路径=新的ArrayList();
私有静态int路径大小=0;
//绘制路径
专用路径;
//绘图和画布点
私人油漆拉丝漆、帆布漆;
//原色
私有int paintColor=0xFF660000;
//帆布
私人帆布;
//画布位图
私有位图画布位图;
私人浮动笔刷大小,lastBrushSize;
公共绘图视图(上下文、属性集属性){
超级(上下文,attrs);
设置绘图();
}
公共void setPattern(字符串newPattern){
使无效();
int patternID=getResources().getIdentifier(newPattern,“drawable”,“com.faisalahsan.paintingapp”);
位图模式bmp=BitmapFactory.decodeResource(getResources(),patternID);
BitmapShader patternBMPShader=新的BitmapShader(patternBMP,Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);
drawPaint.setColor(0xFFFFFFFF);
拉丝漆.定型漆(图案定型漆);
}
专用图纸(){
//获取用于交互的绘图区域设置
drawPath=新路径();
drawPaint=新油漆();
添加(drawPath);
brushSize=getResources().getInteger(R.integer.medium\u size);
lastBrushSize=笔刷大小;
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(真);
drawPaint.设置行程宽度(刷号);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(绘制.连接.圆形);
drawPaint.setStrokeCap(油漆盖圆形);
画布绘制=新绘制(绘制抖动标志);
}
@凌驾
受保护的void onDraw(画布){
对于(路径p:Path){
drawBitmap(canvasBitmap,0,0,canvasPaint);
画布.drawPath(p,drawPaint);
}
}
@凌驾
IzeChanged(intw,inth,intoldw,intoldh)上的受保护的空区{
super.onSizeChanged(w,h,oldw,oldh);
canvasBitmap=Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas=新画布(画布位图);
}
公共void onClickUndo(){
if(path.size()>0){
undoPath.add(path.remove(path.size()-1));
使无效();
}          
}
公共void onClickRedo(){
if(undoPath.size()>0){
add(undoPath.remove(undoPath.size()-1));
使无效();
}
}
@凌驾
公共布尔onTouchEvent(运动事件){
float touchX=event.getX();
float touchY=event.getY();
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
drawPath.moveTo(touchX,toucy);
打破
case MotionEvent.ACTION\u移动:
drawPath.lineTo(touchX,touchY);
打破
case MotionEvent.ACTION\u UP:
drawCanvas.drawPath(drawPath,drawPaint);
drawPath.reset();
drawPath=新路径();
添加(drawPath);
打破
违约:
返回false;
}
使无效();
返回true;
}   
}
当“撤消”从ArrayList“路径”中删除操作时,您不是在画布上“重新绘制”——换句话说,将其从列表中删除不会更改图像。为了“撤消”动作,必须在绘制画布之前重新绘制画布上的内容


在“onDraw”启动时保存画布的状态,然后在调用undo时重新绘制画布。您需要保持画布状态的同步堆栈,以便执行一系列“撤消”和“重做”调用。

您能帮我介绍一些示例或代码吗?请仔细阅读:您缺少“堆栈”端(您正在跟踪“命令”)但不是操作堆栈…出于内存原因,您可能需要每个位图的缓存版本;因此ArrayList bitmaps=new ArrayList();在每次更改之前,您可以在其中存储位图图像的状态。但是,您需要缓存的不仅仅是几个“撤消”选项。对于“重做”,您需要另一个类似ArrayList redoBitmaps的选项