Reputation: 2063
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?
Upvotes: 3
Views: 2545
Reputation: 9569
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;
}
Upvotes: 1
Reputation: 4220
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
Upvotes: 1