简体   繁体   中英

Android Smooth Multi-touch Drawing

I'm trying make a simple Drawing app. I'd like smooth finger drawing simple curves. And use multi-touch. I've following code:

@Override
public void onDraw(Canvas canvas) {
    for (Path path : paths) {
        canvas.drawPath(path, paint);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float xPos = event.getX();
    float yPos = event.getY();

    if (event.getAction() == MotionEvent.ACTION_DOWN)
    {
        path = new Path();
        path.moveTo(xPos, yPos);
    }
    else if (event.getAction() == MotionEvent.ACTION_MOVE)
    {
        path.lineTo(xPos, yPos);
                    paths.add(path);
    }
    else if (event.getAction() == MotionEvent.ACTION_UP)
    {
        path.lineTo(xPos, yPos);
                    paths.add(path);
    }

    invalidate();

    return true;
}

Is where any other way? How can I draw by three fingers and nicely smooth?

The MotionEvent has historical information embedded in it for this type of application. There is a nice example at http://developer.android.com/reference/android/view/MotionEvent.html under the Batching heading

Here example for copy-paste. Just create class that extend View and implement following methods.

private final Paint paint = new Paint(); // Don't forgot to init color, form etc.

@Override
protected void onDraw(Canvas canvas) {
    for (int size = paths.size(), i = 0; i < size; i++) {
        Path path = paths.get(i);
        if (path != null) {
            canvas.drawPath(path, paint);
        }
    }
}

private HashMap<Integer, Float> mX = new HashMap<Integer, Float>();
private HashMap<Integer, Float> mY = new HashMap<Integer, Float>();
private HashMap<Integer, Path> paths = new HashMap<Integer, Path>();

@Override
public boolean onTouchEvent(MotionEvent event) {
    int maskedAction = event.getActionMasked();

    Log.d(TAG, "onTouchEvent");

    switch (maskedAction) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN: {
            for (int size = event.getPointerCount(), i = 0; i < size; i++) {
                Path p = new Path();
                p.moveTo(event.getX(i), event.getY(i));
                paths.put(event.getPointerId(i), p);
                mX.put(event.getPointerId(i), event.getX(i));
                mY.put(event.getPointerId(i), event.getY(i));
            }
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            for (int size = event.getPointerCount(), i = 0; i < size; i++) {
                Path p = paths.get(event.getPointerId(i));
                if (p != null) {
                    float x = event.getX(i);
                    float y = event.getY(i);
                    p.quadTo(mX.get(event.getPointerId(i)), mY.get(event.getPointerId(i)), (x + mX.get(event.getPointerId(i))) / 2,
                            (y + mY.get(event.getPointerId(i))) / 2);
                    mX.put(event.getPointerId(i), event.getX(i));
                    mY.put(event.getPointerId(i), event.getY(i));
                }
            }
            invalidate();
            break;
        }
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_CANCEL: {
            for (int size = event.getPointerCount(), i = 0; i < size; i++) {
                Path p = paths.get(event.getPointerId(i));
                if (p != null) {
                    p.lineTo(event.getX(i), event.getY(i));
                    invalidate();
                    paths.remove(event.getPointerId(i));
                    mX.remove(event.getPointerId(i));
                    mY.remove(event.getPointerId(i));
                }
            }
            break;
        }
    }

    return true;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM