5

I have tried to draw multiple lines like this:

`

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

But when I'm trying to draw something, FPS will slowly decrease. Any ideas how to make it works fine? P.S. Sorry for my English, please

Helisia
  • 568
  • 2
  • 7
  • 23

2 Answers2

6

What you need to do is store the lines inside an arraylist and then read the arraylist onDraw(). try this code for your View Class:

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;
    }
  }
}
Caleb Bramwell
  • 1,332
  • 2
  • 12
  • 24
  • I like your idea, but I meant draw lines like in Paint for Windows, not like line from A to B – Helisia Sep 15 '13 at 08:40
  • I have updated the code. Basically what you want to do is get the stopX and stopY of your line and use them for your startX and startY of your next line. I have included an extra line to check it the line is the first line drawn. – Caleb Bramwell Sep 15 '13 at 08:54
  • @CalebBramwell check this http://stackoverflow.com/questions/16650419/draw-in-canvas-by-finger-android/16650524#16650524 if it helps. tested on samsung galaxy s3 – Raghunandan Sep 15 '13 at 10:49
2

you can use this view if youd like

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();

    }

}
JRowan
  • 6,824
  • 8
  • 40
  • 59