在我的Android应用程序中,我想提供跟踪字母功能,如下图所示:
这里我想提供字母-D的跟踪,为此我需要在用户开始在弧上移动手指时在两点之间绘制弧。在这里,如果用户开始从起点移动手指并在终点处停止,则只有它应该在这些点之间绘制弧。在弧形路径上移动手指时也应该显示弧形。为此我写了下面的代码。我面临的问题是,当在弧形路径上触发ACTION_UP
事件时,它仍然在画布上显示弧形图。但是我想从路径中删除该绘图,如果它在弧路径之间触发ACTION_UP
事件。
这是我的代码:
public class DrawView extends View implements OnTouchListener {
List<Point> pointsD = new ArrayList<Point>();
pointsD.add(new Point(520, 70));
pointsD.add(new Point(520, 335));
pointsD.add(new Point(520, 70));
pointsD.add(new Point(520, 335));
public boolean onTouch(View view, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up(x, y);
invalidate();
break;
default:
break;
}
return true;
}
private void touch_start(float x, float y) {
if (checkPoint(x, y, mLastPointIndex)) {
mPath.reset();
isPathStarted = true;
} else {
isPathStarted = false;
}
}
private void touch_move(float x, float y) {
if (isPathStarted) {
mPath.reset();
Point p = null;
p = pointsD.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
float radius = 1;
RectF oval = new RectF();
oval.set(scalePointX((int) (486 - radius)),scalePointY(70), scalePointX((int) (686 + radius)),
scalePointY((int) (334 + radius)));
if (sweepAngelD <= 180 && startAngleD <= 360) {
mPath.arcTo(oval, startAngleD, sweepAngelD, true);
sweepAngelD += 1;
startAngleD += 2;
mCanvas.drawPath(mPath, mPaint);
}
mPath.reset();
}
private void touch_up(float x, float y) {
mPath.reset();
if (isPathStarted) {
float radius = 1;
RectF oval = new RectF();
oval.set(scalePointX((int) (486 - radius)),
scalePointY(70), scalePointX((int) (686 + radius)),
scalePointY((int) (334 + radius)));
Point p = pointsD.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
mPath.arcTo(oval, startAngleD, sweepAngelD, true);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
++mLastPointIndex;
} else {
sweepAngelD = 1;
startAngleD = 270;
mPath.reset();
}
isPathStarted = false;
}
private boolean checkPoint(float x, float y, int pointIndex){
if (pointIndex == pointsD.size()) {
// out of bounds
return false;
}
point = pointsD.get(pointIndex);
// EDIT changed point.y to poin.x in the first if statement
if (x > (point.x - TOUCH_TOLERANCE)
&& x < (point.x + TOUCH_TOLERANCE)) {
if (y > (point.y - TOUCH_TOLERANCE)
&& y < (point.y + TOUCH_TOLERANCE)) {
return true;
}
}
return false;
}
}
答案 0 :(得分:4)
我编辑了我的代码如下,现在它正在运行..
public class DrawView extends View implements OnTouchListener {
List<Point> pointsD = new ArrayList<Point>();
pointsD.add(new Point(520, 70));
pointsD.add(new Point(520, 335));
pointsD.add(new Point(520, 70));
pointsD.add(new Point(520, 335));
public boolean onTouch(View view, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up(x, y);
invalidate();
break;
default:
break;
}
return true;
}
private void touch_start(float x, float y) {
if (checkPoint(x, y, mLastPointIndex)) {
mPath.reset();
isPathStarted = true;
} else {
isPathStarted = false;
}
}
private void touch_move(float x, float y) {
if (isPathStarted) {
mPath.reset();
Point p = null;
p = pointsD.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
float radius = 1;
RectF oval = new RectF();
oval.set(scalePointX((int) (486 - radius)),scalePointY(70), scalePointX((int) (686 + radius)),
scalePointY((int) (334 + radius)));
if (sweepAngelD <= 180 && startAngleD <= 360) {
mPath.arcTo(oval, startAngleD, sweepAngelD, true);
sweepAngelD += 1;
startAngleD += 2;
}
mPath.reset();
}
private void touch_up(float x, float y) {
mPath.reset();
if (isPathStarted) {
float radius = 1;
RectF oval = new RectF();
oval.set(scalePointX((int) (486 - radius)),
scalePointY(70), scalePointX((int) (686 + radius)),
scalePointY((int) (334 + radius)));
Point p = pointsD.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
mPath.arcTo(oval, startAngleD, sweepAngelD, true);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
++mLastPointIndex;
} else {
sweepAngelD = 1;
startAngleD = 270;
mPath.reset();
}
isPathStarted = false;
}
private boolean checkPoint(float x, float y, int pointIndex){
if (pointIndex == pointsD.size()) {
// out of bounds
return false;
}
point = pointsD.get(pointIndex);
// EDIT changed point.y to poin.x in the first if statement
if (x > (point.x - TOUCH_TOLERANCE)
&& x < (point.x + TOUCH_TOLERANCE)) {
if (y > (point.y - TOUCH_TOLERANCE)
&& y < (point.y + TOUCH_TOLERANCE)) {
return true;
}
}
return false;
}
}