Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了android(多点触控)绘图app撤消功能大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在绘制一个绘图应用程序,onTouchEvents是标准的,并且想要添加Undo()函数删除最后绘制的路径.

声明:

int tHelastLinEID=0;
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 HashMap<Integer,Path> pathMap; // current Paths being drawn
private HashMap<Integer,Path> reservedpathMap; // for saving the paths being undone
private HashMap<Integer,Point> prevIoUsPointMap; // current Points

构造函数

pathMap = new HashMap<Integer,Path>();
reservedpathMap = new HashMap <Integer,Path>(); // for storing path being undone
prevIoUsPointMap = new HashMap<Integer,Point>();

onDraw有:

@Override
   protected void onDraw(Canvas canvas) 
   {
       canvas.drawBitmap(bitmap,paintScreen);
       // for each path currently being drawn
       for (Integer key : pathMap.keySet()) 
            canvas.drawPath(pathMap.get(key),paintLinE); // draw line     
   }

的onTouchEvent:

@Override
   public Boolean onTouchEvent(MotionEvent event) 
   {                  
      int action = event.getActionMasked(); // event type 
      int actionIndex = event.getActionIndex(); // pointer (i.e.,finger)

      if (action == MotionEvent.ACTION_DOWN) 
      {       
          touchStarted(event.getX(actionIndeX),event.getY(actionIndeX),event.getPointerId(actionIndeX));
      } 
      else if (action == MotionEvent.ACTION_Up) 
      {
          touchEnded(event.getPointerId(actionIndeX));
      } 
      else 
      {
         touchMoved(event); 
      } 

      invalidate();
      return true; 
   }

touchStarted:

private void touchStarted(float x,float y,int linEID) // linEID represents how many fingers,1 finger 1 line
   {      
      Path path; // used to store the path for the given touch id
      Point point; // used to store the last point in path

      // if there is already a path for linEID
      if (pathMap.containsKey(linEID)) 
      {
         path = pathMap.get(linEID); // get the Path
         path.reset(); // reset the Path because a new touch has started
         point = prevIoUsPointMap.get(linEID); // get Path's last point
      } 
      else 
      {
         path = new Path(); // create a new Path
         pathMap.put(linEID,path); // add the Path to Map
         point = new Point(); // create a new Point
         prevIoUsPointMap.put(linEID,point); // add the Point to the Map
      } 

      path.moveTo(x,y);
      point.x = (int) x;  
      point.y = (int) y;  
   }

touchMoved:

private void touchMoved(MotionEvent event) 
   {
      // for each of the pointers in the given MotionEvent
      for (int i = 0; i < event.getPointerCount(); i++) 
      {
         // get the pointer ID and pointer index
         int pointerID = event.getPointerId(i);
         int pointerIndex = event.findPointerIndex(pointerID);

         // if there is a path associated with the pointer
         if (pathMap.containsKey(pointerID)) 
         {
            float newX = event.getX(pointerIndeX);
            float newY = event.getY(pointerIndeX);

            // get the Path and prevIoUs Point associated with this pointer
            Path path = pathMap.get(pointerID);
            Point point = prevIoUsPointMap.get(pointerID);

            float deltaX = Math.abs(newX - point.X);
            float deltaY = Math.abs(newY - point.y);
            if (deltaX >= TOUCH_TOLERANCE || deltaY >= TOUCH_TOLERANCE) 
            {
               path.quadTo(point.x,point.y,((newX + point.X)/2),((newY + point.y)/2));

               point.x = (int) newX ; 
               point.y = (int) newY ; 
         } 
      }      
   }

touchEnded:

private void touchEnded(int linEID)
   {
      Path path = pathMap.get(linEID); // get the corresponding Path
      bitmapCanvas.drawPath(path,paintLinE); 
      path.reset();           
   }

撤消:

public void undo()
   {
       Toast.makeText(getContext(),"undo button pressed" + tHelastLinEID,Toast.LENGTH_SHORT).show();

       Path path = pathMap.get(tHelastLinEID); 
       reservedpathMap.put(tHelastLinEID,path); // add the Path to reservedpathMap for later redo
       pathMap.remove(tHelastLinEID);   

       invalidate();          
   }

题:

我正在尝试使用如上所示的代码实现UNDO方法:尝试从HashMap路径图中删除tHelastLindId键(并将其放到HashMap后面的稍后重做的路径映射),这样当invalidate()时它将调用OnDraw()并且重绘

for (Integer key : pathMap.keySet()) 
                canvas.drawPath(pathMap.get(key),paintLinE);

但是,按下撤消按钮可以启动“撤消被点击”的祝酒,但最后绘制的行无法消失.

有人可以给我一个Undo()和Redo()的线索吗?提前谢谢了!!

解决方法

@H_874_60@ 因为我可以理解你想要实现的目标,所以你希望能够在画布上绘制线条,之后为你的项目制作UNDO功能.首先,我认为当您向阵列添加路径时,应该是当用户用touchEnded方法抬起手指时.其次,我真的没有得到关于两个/三个手指的解释?你在画布上支持多点触控吗?这是我之前在一些示例中使用的实现,用于在具有撤消实现的画布上绘图.希望它能帮助你更清楚地做到:

public void onClickUndo () { 
if (paths.size()>0) { 
   undonePaths.add(paths.remove(paths.size()-1))
   invalidate();
 }
    else
     //toast the user 
}

public void onClickRedo (){
   if (undonePaths.size()>0) { 
       paths.add(undonePaths.remove(undonePaths.size()-1)) 
       invalidate();
   } 
   else 
     //toast the user 
}

以下是您触摸方法的等价物:

@Override
protected void onSizeChanged(int w,int h,int oldw,int oldh) {
    super.onSizeChanged(w,h,oldw,oldh);
}

@Override
protected void onDraw(Canvas canvas) {            

    for (Path p : paths){
        canvas.drawPath(p,mPaint);
    }

}

private float mX,mY;
private static final float TOUCH_TOLERANCE = 0;

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);
    // commit the path to our offscreen
    mCanvas.drawPath(mPath,mPaint);
    // kill this so we don't double draw            
    mPath = new Path();
    paths.add(mPath);
}

从这里你可以看到路径是我存储路径的arraylist.如果你告诉我为什么你需要把你的路径放在hashmap中,我可能会更有帮助.

大佬总结

以上是大佬教程为你收集整理的android(多点触控)绘图app撤消功能全部内容,希望文章能够帮你解决android(多点触控)绘图app撤消功能所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。