Android 画布绘制直线

12

我有一个自定义布局,根据触摸输入绘制一条线。我已经让它画出了一条线,但当用户触摸屏幕时,该线会消失并绘制一条新线。我希望它能够画出一条新线并将以前的线保留在那里。

这是我的代码:

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;

    public class DrawView extends View {
      Paint paint = new Paint();
      float startX;
      float startY;
      float stopX;
      float stopY;

      public DrawView(Context context, AttributeSet attrs) {
        super(context, attrs);

        paint.setAntiAlias(true);
        paint.setStrokeWidth(6f);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
      }

      @Override
      protected void onDraw(Canvas canvas) {
          canvas.drawLine(startX, startY, stopX, stopY, paint);
      }

      @Override
              public boolean onTouchEvent(MotionEvent event) {

       switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            startX = event.getX();
            startY = event.getY();
          return true;
        case MotionEvent.ACTION_MOVE:
          stopX = event.getX();
          stopY = event.getY();
         break;
        case MotionEvent.ACTION_UP:    
            stopX = event.getX();
            stopY = event.getY();
          break;
        default:
          return false;
        }
          Invalidate();
        return true;
      }
    } 
1个回答

18

你需要存储所有行而不仅仅是最后一行。
以下代码完全未经测试,但希望能给你一个大致的思路。

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;

class Line {
  float startX, startY, stopX, stopY;
  public Line(float startX, float startY, float stopX, float stopY) {
    this.startX = startX;
    this.startY = startY;
    this.stopX = stopX;
    this.stopY = stopY;
  }
  public Line(float startX, float startY) { // for convenience
    this(startX, startY, startX, startY);
  }
}

public class DrawView extends View {
  Paint paint = new Paint();
  ArrayList<Line> lines = new ArrayList<Line>();

  public DrawView(Context context, AttributeSet attrs) {
    super(context, attrs);

    paint.setAntiAlias(true);
    paint.setStrokeWidth(6f);
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    for (Line l : lines) {
      canvas.drawLine(l.startX, l.startY, l.stopX, l.stopY, paint);
    }
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      lines.add(new Line(event.getX(), event.getY()));
      return true;
    }
    else if ((event.getAction() == MotionEvent.ACTION_MOVE ||
        event.getAction() == MotionEvent.ACTION_UP) &&
        lines.size() > 0) {
      Line current = lines.get(lines.size() - 1);
      current.stopX = event.getX();
      current.stopY = event.getY();
      invalidate();
      return true;
    }
    else {
      return false;
    }
  }
}

一个问题是它一直在重新绘制画布。我如何停止它重新绘制画布? - Caleb Bramwell
我该如何调整特定行的大小? - Sai Aditya
1
如果所有线条都相连,最好使用路径:Path path = new Path(); path.moveTo(0, 0); path.lineTo(0,50); path.lineTo(100,50); path.lineTo(100, 0); path.close(); - Jorge Arimany
2
@FaizanHaidarKhan 你应该提出一个单独的问题(最好附上你已经尝试过的内容)。一些提示:水平线具有相同的startY和stopY,而垂直线具有相同的startX和stopX。因此,要使当前行水平,您可以使用current.stopX = event.getX(); current.stopY = current.startY;。要确定用户是否希望当前行为水平还是垂直,您可以将事件坐标与起始坐标进行比较,并选择具有最大差异的轴。 - tom
1
@FaizanHaidarKhan 对于目标符号,您可以在实例变量(如实例变量“paint”和“lines”)中存储最近的触摸坐标,并在onDraw()方法中使用这些坐标来绘制符号。您可能需要添加一个标志来记住用户手指当前是否按下,并且只有在用户手指按下时才绘制符号。 - tom
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接