gpt4 book ai didi

android(多点触控)绘图应用程序撤消功能

转载 作者:太空宇宙 更新时间:2023-11-03 10:50:01 24 4
gpt4 key购买 nike

我正在开发一个绘图应用程序,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, 0, 0, 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;
}

触摸移动:

   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 ;
}
}
}

触摸结束:

   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 pathmap 中删除 thelastLindId 键(并放入 HashMap reservedpathMap 以便稍后重做)这样当 invalidate() 时它将调用 OnDraw() 并通过

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

但是,按下撤消按钮可以启动“撤消被点击”的 toast ,但最后绘制的线条无法消失。

任何人都可以给我一个关于 Undo() 和 Redo() 的线索吗?非常感谢!!

最佳答案

据我了解您想要实现的目标,您希望能够在 Canvas 上绘制线条,然后为您的项目提供撤消功能。首先,我认为将路径添加到数组的时刻应该是用户在 touchEnded 方法中抬起手指时。其次,我真的不明白你解释的关于两个/三个手指的事情?你的 Canvas 支持多点触控吗?这是我之前在一些示例中使用的实现,用于在带有撤消实现的 Canvas 上绘图。希望它能帮助您使事情更清楚:

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);
}

正如您从这里看到的,paths 是我存储路径的数组列表。如果你告诉我为什么你需要把你的路径放在 hashmap 中,也许我会更有帮助。

关于android(多点触控)绘图应用程序撤消功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14941015/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com