如何用手指在Android系统上绘制多条线?

5
我尝试过像这样绘制多条线:

`

l1 = new Path();

l2 = new Path();
l3 = new Path();
l4 = new Path();`
---
`mPathList.add(l1...l4);`
---

    `public void onDraw(Canvas canvas) {
    ...

for (Path path : mPathList) {
canvas.drawPath(path, mOverlayPaint);

    }
    ...
    }`

    ---
    `case MotionEvent.ACTION_MOVE:
    int X = (int)me.getRawX();
    int Y = (int)me.getRawY();

    l1.moveTo(X, Y);
    l2.moveTo(X + 5, Y);
    l3.moveTo(X + 10, Y);
    l4.moveTo(X + 15, Y);
    break;`

但是当我尝试绘制一些东西时,FPS会慢慢下降。有什么办法可以使其正常工作吗? 附注:抱歉我的英文不好,请见谅。


在演示中遵循Fingerpaint API。 - Raghunandan
2个回答

6
你需要做的是将这些行存储到一个ArrayList中,然后在onDraw()方法中读取ArrayList。请尝试使用以下代码来修改你的View类:

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, 
  float joinX, joinY = 0;
  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) {
      if (joinX <= 0 || joinY <= 0) lines.add(new Line(event.getX(), event.getY()));
      else lines.add(new Line(joinX, joinY);
      return true;
    }
    else if ((event.getAction() == MotionEvent.ACTION_MOVE) &&
        lines.size() > 0) {
      Line current = lines.get(lines.size() - 1);
      current.stopX = event.getX();
      current.stopY = event.getY();
      Invalidate();
      return true;
    }
    else if ((event.getAction() == MotionEvent.ACTION_UP) &&
        lines.size() > 0 {
      Line current = lines.get(lines.size() - 1);
      current.stopX = event.getX();
      current.stopY = event.getY();
      joinX = event.getX();
      joinY = event.getY();
      Invalidate();
      return true;
    }
    else {
      return false;
    }
  }
}

我喜欢你的想法,但我的意思是像Windows画图软件中那样绘制线条,而不是从A到B的直线。 - Helisia
我已经更新了代码。基本上你想做的是获取线的stopX和stopY,并将它们用作下一条线的startX和startY。我还包括了一行额外的代码来检查这条线是否是第一条画出的线。 - Caleb Bramwell
@CalebBramwell 请查看此链接:https://dev59.com/_WQn5IYBdhLWcg3wrouL#16650524 如果有帮助的话。已在三星Galaxy S3上测试过。 - Raghunandan

2

如果您愿意,可以使用此视图。

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.LruCache;
import android.view.MotionEvent;
import android.view.View;

public class MyDrawView extends View {
    public Bitmap  mBitmap;
    public Canvas  mCanvas;
    private Path    mPath;
    private Paint   mBitmapPaint;
    private Paint   mPaint;


    public MyDrawView(Context c, AttributeSet attrs) {
        super(c, attrs);

        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(0xFF000000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(9);

    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, mPaint);


    }

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;
        }
    }
    private void touch_up() {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
    }

    @Override
    public boolean onTouchEvent(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();
                invalidate();
                break;
        }
        return true;
    }

    public Bitmap getBitmap()
    {
        //this.measure(100, 100);
        //this.layout(0, 0, 100, 100);
        this.setDrawingCacheEnabled(true);  
        this.buildDrawingCache();
       Bitmap bmp = Bitmap.createBitmap(this.getDrawingCache());   
        this.setDrawingCacheEnabled(false);


    return bmp;
    }



    public void clear(){
        mBitmap.eraseColor(Color.GREEN);
        invalidate();
        System.gc();

    }

}

1
它在我的设备上运行良好,我不知道,我正在使用索尼 Xperia,如果这不能帮助到你,抱歉。 - JRowan

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