首页 文章

Android画布 - 在点之间绘制弧并从路径中删除弧

提问于
浏览
3

在我的Android应用程序中,我想提供跟踪字母功能,如下图所示:

enter image description here

在这里,我想提供字母-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;
}
}

1 回答

  • 3

    我编辑了我的代码如下,现在它正在工作..

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

相关问题