I can actually draw lines with finger in my app using the FingerPaint in API Demos
given in samples of Android SDK
. But how to draw these lines with finger only along points placed on the screen. I want something like in this app:https://play.google.com/store/apps/details?id=zok.android.dots
I just want to draw line between point 1 and point 2 with finger. The line between 1 and 2 must be drawn only if the point 2 is touched, else it shouldn't be drawn. Likewise, again from point 2 to point 3 and so on.
Please help me with a code for this.
Thanks in advance
P.S. Please have a look at the app in the link well before answering so that you would have a clear idea about my requirement.
Update:
public class PaintView extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mPaint;
private static final int TOUCH_TOLERANCE_DP = 20;
private static final int BACKGROUND = 0xFFDDDDDD;
private List<Point> mPoints = new ArrayList<Point>();
private int mLastPointIndex = 0;
private int mTouchTolerance;
private boolean isPathStarted = false;
public PaintView(Context context) {
super(context);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
// TODO just test points
Point p1 = new Point(133, 123);
Point p2 = new Point(149, 136);
Point p3 = new Point(182, 136);
Point p4 = new Point(206, 118);
Point p5 = new Point(208, 87);
Point p6 = new Point(187, 71);
Point p7 = new Point(144, 78);
Point p8 = new Point(124, 101);
Point p9 = new Point(113, 128);
Point p10 = new Point(112, 157);
Point p11 = new Point(119, 188);
Point p12 = new Point(134, 209);
Point p13 = new Point(162, 228);
Point p14 = new Point(194, 238);
Point p15 = new Point(232, 240);
Point p16 = new Point(263, 237);
Point p17 = new Point(289, 224);
Point p18 = new Point(315, 204);
Point p19 = new Point(332, 174);
Point p20 = new Point(339, 128);
Point p21 = new Point(329, 95);
Point p22 = new Point(304, 73);
Point p23 = new Point(280, 69);
Point p24 = new Point(254, 87);
Point p25 = new Point(248, 116);
Point p26 = new Point(259, 143);
Point p27 = new Point(278, 153);
Point p28 = new Point(241, 157);
Point p29 = new Point(192, 160);
Point p30 = new Point(150, 159);
mPoints.add(p1);
mPoints.add(p2);
mPoints.add(p3);
mPoints.add(p4);
mPoints.add(p5);
mPoints.add(p6);
mPoints.add(p7);
mPoints.add(p8);
mPoints.add(p9);
mPoints.add(p10);
mPoints.add(p11);
mPoints.add(p12);
mPoints.add(p13);
mPoints.add(p14);
mPoints.add(p15);
mPoints.add(p16);
mPoints.add(p17);
mPoints.add(p18);
mPoints.add(p19);
mPoints.add(p20);
mPoints.add(p21);
mPoints.add(p22);
mPoints.add(p23);
mPoints.add(p24);
mPoints.add(p25);
mPoints.add(p26);
mPoints.add(p27);
mPoints.add(p28);
mPoints.add(p29);
mPoints.add(p30);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
// TODO just test points
Point p1 = new Point(133, 123);
Point p2 = new Point(149, 136);
Point p3 = new Point(182, 136);
Point p4 = new Point(206, 118);
Point p5 = new Point(208, 87);
Point p6 = new Point(187, 71);
Point p7 = new Point(144, 78);
Point p8 = new Point(124, 101);
Point p9 = new Point(113, 128);
Point p10 = new Point(112, 157);
Point p11 = new Point(119, 188);
Point p12 = new Point(134, 209);
Point p13 = new Point(162, 228);
Point p14 = new Point(194, 238);
Point p15 = new Point(232, 240);
Point p16 = new Point(263, 237);
Point p17 = new Point(289, 224);
Point p18 = new Point(315, 204);
Point p19 = new Point(332, 174);
Point p20 = new Point(339, 128);
Point p21 = new Point(329, 95);
Point p22 = new Point(304, 73);
Point p23 = new Point(280, 69);
Point p24 = new Point(254, 87);
Point p25 = new Point(248, 116);
Point p26 = new Point(259, 143);
Point p27 = new Point(278, 153);
Point p28 = new Point(241, 157);
Point p29 = new Point(192, 160);
Point p30 = new Point(150, 159);
mPoints.add(p1);
mPoints.add(p2);
mPoints.add(p3);
mPoints.add(p4);
mPoints.add(p5);
mPoints.add(p6);
mPoints.add(p7);
mPoints.add(p8);
mPoints.add(p9);
mPoints.add(p10);
mPoints.add(p11);
mPoints.add(p12);
mPoints.add(p13);
mPoints.add(p14);
mPoints.add(p15);
mPoints.add(p16);
mPoints.add(p17);
mPoints.add(p18);
mPoints.add(p19);
mPoints.add(p20);
mPoints.add(p21);
mPoints.add(p22);
mPoints.add(p23);
mPoints.add(p24);
mPoints.add(p25);
mPoints.add(p26);
mPoints.add(p27);
mPoints.add(p28);
mPoints.add(p29);
mPoints.add(p30);
}
public PaintView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
}
@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
super.onSizeChanged(width, height, oldWidth, oldHeight);
clear();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(BACKGROUND);
canvas.drawBitmap(mBitmap, 0, 0, null);
canvas.drawPath(mPath, mPaint);
// TODO remove if you dont want points to be drawn
for (Point point : mPoints) {
canvas.drawPoint(point.x, point.y, mPaint);
}
}
@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(x, y);
invalidate();
break;
}
return true;
}
private void touch_start(float x, float y) {
if (checkPoint(x, y, mLastPointIndex)) {
mPath.reset();
// user starts from given point so path can beis started
isPathStarted = true;
} else {
// user starts move from point which doen's belongs to mPinst list
isPathStarted = false;
}
}
//ADDED WITH LAST EDIT
private void touch_move(float x, float y) {
// draw line with finger move
if (isPathStarted) {
mPath.reset();
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
if (checkPoint(x, y, mLastPointIndex + 1)) {
p = mPoints.get(mLastPointIndex + 1);
mPath.lineTo(p.x, p.y);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
++mLastPointIndex;
} else {
mPath.lineTo(x, y);
}
}
}
/**
* Draws line.
*/
private void touch_up(float x, float y) {
mPath.reset();
if (checkPoint(x, y, mLastPointIndex + 1) && isPathStarted) {
// move finished at valid point so draw whole line
// start point
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
// end point
p = mPoints.get(mLastPointIndex + 1);
mPath.lineTo(p.x, p.y);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
// increment point index
++mLastPointIndex;
isPathStarted = false;
}
}
/**
* Sets paint
*
* @param paint
*/
public void setPaint(Paint paint) {
this.mPaint = paint;
}
/**
* Returns image as bitmap
*
* @return
*/
public Bitmap getBitmap() {
return mBitmap;
}
/**
* Clears canvas
*/
public void clear() {
mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(BACKGROUND);
mCanvas.setBitmap(mBitmap);
invalidate();
}
/**
* Checks if user touch point with some tolerance
*/
private boolean checkPoint(float x, float y, int pointIndex) {
if (pointIndex == mPoints.size()) {
// out of bounds
return false;
}
Point point = mPoints.get(pointIndex);
if (x > (point.x - mTouchTolerance) && x < (point.y + mTouchTolerance)) {
if (y > (point.y - mTouchTolerance) && y < (point.y + mTouchTolerance)) {
return true;
}
}
return false;
}
public List<Point> getPoints() {
return mPoints;
}
public void setPoints(List<Point> points) {
this.mPoints = points;
}
private int dp2px(int dp) {
Resources r = getContext().getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
return (int) px;
}
}
Still am I missing something?
I done something similar but I'm not sure if it's exactly what you're expecting. Try this implementation of PaintView
:
Edit:
Added touch_move()
to drawn line along finger move.
Edit2:
To draw multiple lines with one move change touch_move()
method to this one:
private void touch_move(float x, float y) {
// draw line with finger move
if (isPathStarted) {
mPath.reset();
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
if (checkPoint(x, y, mLastPointIndex + 1)) {
p = mPoints.get(mLastPointIndex + 1);
mPath.lineTo(p.x, p.y);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
++mLastPointIndex;
} else {
mPath.lineTo(x, y);
}
}
}
_
public class PaintView extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mPaint;
private static final int TOUCH_TOLERANCE_DP = 24;
private static final int BACKGROUND = 0xFFDDDDDD;
private List<Point> mPoints = new ArrayList<Point>();
private int mLastPointIndex = 0;
private int mTouchTolerance;
private boolean isPathStarted = false;
public PaintView(Context context) {
super(context);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
// TODO just test points
Point p1 = new Point(20, 20);
Point p2 = new Point(100, 100);
Point p3 = new Point(200, 250);
Point p4 = new Point(280, 400);
Point p5 = new Point(350, 600);
Point p6 = new Point(400, 500);
mPoints.add(p1);
mPoints.add(p2);
mPoints.add(p3);
mPoints.add(p4);
mPoints.add(p5);
mPoints.add(p6);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
// TODO just test points
Point p1 = new Point(20, 20);
Point p2 = new Point(100, 100);
Point p3 = new Point(200, 250);
Point p4 = new Point(280, 400);
Point p5 = new Point(350, 600);
Point p6 = new Point(400, 500);
mPoints.add(p1);
mPoints.add(p2);
mPoints.add(p3);
mPoints.add(p4);
mPoints.add(p5);
mPoints.add(p6);
}
public PaintView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
}
@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
super.onSizeChanged(width, height, oldWidth, oldHeight);
clear();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(BACKGROUND);
canvas.drawBitmap(mBitmap, 0, 0, null);
canvas.drawPath(mPath, mPaint);
// TODO remove if you dont want points to be drawn
for (Point point : mPoints) {
canvas.drawPoint(point.x, point.y, mPaint);
}
}
@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(x, y);
invalidate();
break;
}
return true;
}
private void touch_start(float x, float y) {
if (checkPoint(x, y, mLastPointIndex)) {
mPath.reset();
// user starts from given point so path can beis started
isPathStarted = true;
} else {
// user starts move from point which doen's belongs to mPinst list
isPathStarted = false;
}
}
//ADDED WITH LAST EDIT
private void touch_move(float x, float y) {
// draw line with finger move
if (isPathStarted) {
mPath.reset();
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
mPath.lineTo(x, y);
}
}
/**
* Draws line.
*/
private void touch_up(float x, float y) {
mPath.reset();
if (checkPoint(x, y, mLastPointIndex + 1) && isPathStarted) {
// move finished at valid point so draw whole line
// start point
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
// end point
p = mPoints.get(mLastPointIndex + 1);
mPath.lineTo(p.x, p.y);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
// increment point index
++mLastPointIndex;
isPathStarted = false;
}
}
/**
* Sets paint
*
* @param paint
*/
public void setPaint(Paint paint) {
this.mPaint = paint;
}
/**
* Returns image as bitmap
*
* @return
*/
public Bitmap getBitmap() {
return mBitmap;
}
/**
* Clears canvas
*/
public void clear() {
mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(BACKGROUND);
mCanvas.setBitmap(mBitmap);
invalidate();
}
/**
* Checks if user touch point with some tolerance
*/
private boolean checkPoint(float x, float y, int pointIndex) {
if (pointIndex == mPoints.size()) {
// out of bounds
return false;
}
Point point = mPoints.get(pointIndex);
//EDIT changed point.y to poin.x in the first if statement
if (x > (point.x - mTouchTolerance) && x < (point.x + mTouchTolerance)) {
if (y > (point.y - mTouchTolerance) && y < (point.y + mTouchTolerance)) {
return true;
}
}
return false;
}
public List<Point> getPoints() {
return mPoints;
}
public void setPoints(List<Point> points) {
this.mPoints = points;
}
private int dp2px(int dp) {
Resources r = getContext().getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
return (int) px;
}
}
I used it from xml but you can also create it from code, simple xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.example.lecho.PaintView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With