Tôi cần xây dựng một dự án để vẽ trên canvas bằng ngón tay,
để có được sự kiện chạm và sự kiện chuyển động của ngón tay tôi và từ đó vẽ.
Bất kỳ ai có thể tư vấn cho tôi cách bắt đầu dự án,
và thành phần tốt nhất để làm điều như thế này là gì?
Tôi cần xây dựng một dự án để vẽ trên canvas bằng ngón tay,
để có được sự kiện chạm và sự kiện chuyển động của ngón tay tôi và từ đó vẽ.
Bất kỳ ai có thể tư vấn cho tôi cách bắt đầu dự án,
và thành phần tốt nhất để làm điều như thế này là gì?
Câu trả lời:
Bắt đầu Bằng cách xem qua bản demo Fingerpaint trong mẫu sdk.
Một mẫu khác:
public class MainActivity extends Activity {
DrawingView dv ;
private Paint mPaint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dv = new DrawingView(this);
setContentView(dv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
}
public class DrawingView extends View {
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
public DrawingView(Context c) {
super(c);
context=c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
}
@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) {
super.onDraw(canvas);
canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath( mPath, mPaint);
canvas.drawPath( circlePath, circlePaint);
}
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;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
// 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;
}
}
}
Chụp nhanh
Giải trình :
Bạn đang tạo một lớp dạng xem sau đó mở rộng Dạng xem. Bạn ghi đè onDraw (). Bạn thêm đường dẫn nơi ngón tay chạm và di chuyển. Bạn ghi đè onTouch () của mục đích này. Trong onDraw (), bạn vẽ các đường dẫn bằng cách sử dụng sơn bạn chọn. Bạn nên gọi voidate () để làm mới chế độ xem.
Để chọn các tùy chọn, bạn có thể nhấp vào menu và chọn các tùy chọn.
Dưới đây có thể được sử dụng như một tài liệu tham khảo. Bạn có thể sửa đổi bên dưới theo nhu cầu của bạn.
public class FingerPaintActivity extends Activity
implements ColorPickerDialog.OnColorChangedListener {
MyView mv;
AlertDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mv= new MyView(this);
mv.setDrawingCacheEnabled(true);
mv.setBackgroundResource(R.drawable.afor);//set the back ground if you wish to
setContentView(mv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(20);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}
private Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
public void colorChanged(int color) {
mPaint.setColor(color);
}
public class MyView extends View {
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
public MyView(Context c) {
super(c);
context=c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@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) {
super.onDraw(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) {
//showDialog();
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();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
//mPaint.setMaskFilter(null);
}
@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;
}
}
private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
private static final int BLUR_MENU_ID = Menu.FIRST + 2;
private static final int ERASE_MENU_ID = Menu.FIRST + 3;
private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;
private static final int Save = Menu.FIRST + 5;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');
menu.add(0, Save, 0, "Save").setShortcut('5', 'z');
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
switch (item.getItemId()) {
case COLOR_MENU_ID:
new ColorPickerDialog(this, this, mPaint.getColor()).show();
return true;
case EMBOSS_MENU_ID:
if (mPaint.getMaskFilter() != mEmboss) {
mPaint.setMaskFilter(mEmboss);
} else {
mPaint.setMaskFilter(null);
}
return true;
case BLUR_MENU_ID:
if (mPaint.getMaskFilter() != mBlur) {
mPaint.setMaskFilter(mBlur);
} else {
mPaint.setMaskFilter(null);
}
return true;
case ERASE_MENU_ID:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaint.setAlpha(0x80);
return true;
case SRCATOP_MENU_ID:
mPaint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.SRC_ATOP));
mPaint.setAlpha(0x80);
return true;
case Save:
AlertDialog.Builder editalert = new AlertDialog.Builder(FingerPaintActivity.this);
editalert.setTitle("Please Enter the name with which you want to Save");
final EditText input = new EditText(FingerPaintActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT);
input.setLayoutParams(lp);
editalert.setView(input);
editalert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String name= input.getText().toString();
Bitmap bitmap = mv.getDrawingCache();
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
File file = new File("/sdcard/"+name+".png");
try
{
if(!file.exists())
{
file.createNewFile();
}
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 10, ostream);
ostream.close();
mv.invalidate();
}
catch (Exception e)
{
e.printStackTrace();
}finally
{
mv.setDrawingCacheEnabled(false);
}
}
});
editalert.show();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Bộ chọn màu
public class ColorPickerDialog extends Dialog {
public interface OnColorChangedListener {
void colorChanged(int color);
}
private OnColorChangedListener mListener;
private int mInitialColor;
private static class ColorPickerView extends View {
private Paint mPaint;
private Paint mCenterPaint;
private final int[] mColors;
private OnColorChangedListener mListener;
ColorPickerView(Context c, OnColorChangedListener l, int color) {
super(c);
mListener = l;
mColors = new int[] {
0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
0xFFFFFF00, 0xFFFF0000
};
Shader s = new SweepGradient(0, 0, mColors, null);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(s);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(32);
mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(color);
mCenterPaint.setStrokeWidth(5);
}
private boolean mTrackingCenter;
private boolean mHighlightCenter;
@Override
protected void onDraw(Canvas canvas) {
float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
canvas.translate(CENTER_X, CENTER_X);
canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
if (mTrackingCenter) {
int c = mCenterPaint.getColor();
mCenterPaint.setStyle(Paint.Style.STROKE);
if (mHighlightCenter) {
mCenterPaint.setAlpha(0xFF);
} else {
mCenterPaint.setAlpha(0x80);
}
canvas.drawCircle(0, 0,
CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
mCenterPaint);
mCenterPaint.setStyle(Paint.Style.FILL);
mCenterPaint.setColor(c);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
}
private static final int CENTER_X = 100;
private static final int CENTER_Y = 100;
private static final int CENTER_RADIUS = 32;
private int floatToByte(float x) {
int n = java.lang.Math.round(x);
return n;
}
private int pinToByte(int n) {
if (n < 0) {
n = 0;
} else if (n > 255) {
n = 255;
}
return n;
}
private int ave(int s, int d, float p) {
return s + java.lang.Math.round(p * (d - s));
}
private int interpColor(int colors[], float unit) {
if (unit <= 0) {
return colors[0];
}
if (unit >= 1) {
return colors[colors.length - 1];
}
float p = unit * (colors.length - 1);
int i = (int)p;
p -= i;
// now p is just the fractional part [0...1) and i is the index
int c0 = colors[i];
int c1 = colors[i+1];
int a = ave(Color.alpha(c0), Color.alpha(c1), p);
int r = ave(Color.red(c0), Color.red(c1), p);
int g = ave(Color.green(c0), Color.green(c1), p);
int b = ave(Color.blue(c0), Color.blue(c1), p);
return Color.argb(a, r, g, b);
}
private int rotateColor(int color, float rad) {
float deg = rad * 180 / 3.1415927f;
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
ColorMatrix cm = new ColorMatrix();
ColorMatrix tmp = new ColorMatrix();
cm.setRGB2YUV();
tmp.setRotate(0, deg);
cm.postConcat(tmp);
tmp.setYUV2RGB();
cm.postConcat(tmp);
final float[] a = cm.getArray();
int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
return Color.argb(Color.alpha(color), pinToByte(ir),
pinToByte(ig), pinToByte(ib));
}
private static final float PI = 3.1415926f;
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX() - CENTER_X;
float y = event.getY() - CENTER_Y;
boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTrackingCenter = inCenter;
if (inCenter) {
mHighlightCenter = true;
invalidate();
break;
}
case MotionEvent.ACTION_MOVE:
if (mTrackingCenter) {
if (mHighlightCenter != inCenter) {
mHighlightCenter = inCenter;
invalidate();
}
} else {
float angle = (float)java.lang.Math.atan2(y, x);
// need to turn angle [-PI ... PI] into unit [0....1]
float unit = angle/(2*PI);
if (unit < 0) {
unit += 1;
}
mCenterPaint.setColor(interpColor(mColors, unit));
invalidate();
}
break;
case MotionEvent.ACTION_UP:
if (mTrackingCenter) {
if (inCenter) {
mListener.colorChanged(mCenterPaint.getColor());
}
mTrackingCenter = false; // so we draw w/o halo
invalidate();
}
break;
}
return true;
}
}
public ColorPickerDialog(Context context,
OnColorChangedListener listener,
int initialColor) {
super(context);
mListener = listener;
mInitialColor = initialColor;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OnColorChangedListener l = new OnColorChangedListener() {
public void colorChanged(int color) {
mListener.colorChanged(color);
dismiss();
}
};
setContentView(new ColorPickerView(getContext(), l, mInitialColor));
setTitle("Pick a Color");
}
}
Canvas mCanvas
? bởi vì bạn sử dụngonDraw(Canvas canvas)
Về mã đẹp của Raghunandan ở trên.
Nhiều người đã hỏi làm thế nào để "xóa" bản vẽ. Đây là cách để làm điều đó:
public void clearDrawing()
{
Utils.Log("RaghunandanDraw, how to clear....");
setDrawingCacheEnabled(false);
// don't forget that one and the match below,
// or you just keep getting a duplicate when you save.
onSizeChanged(width, height, width, height);
invalidate();
setDrawingCacheEnabled(true);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
width = w; // don't forget these
height = h;
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
Nhiều người đã hỏi làm thế nào để "cứu" bản vẽ. Đây là cách để làm điều đó:
public DrawingView(Context c)
{
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
etc...
// in the class where you set up the view, add this:
setDrawingCacheEnabled( true );
}
public void saveDrawing()
{
Bitmap whatTheUserDrewBitmap = getDrawingCache();
// don't forget to clear it (see above) or you just get duplicates
// almost always you will want to reduce res from the very high screen res
whatTheUserDrewBitmap =
ThumbnailUtils.extractThumbnail(whatTheUserDrewBitmap, 256, 256);
// NOTE that's an incredibly useful trick for cropping/resizing squares
// while handling all memory problems etc
// http://stackoverflow.com/a/17733530/294884
// you can now save the bitmap to a file, or display it in an ImageView:
ImageView testArea = ...
testArea.setImageBitmap( whatTheUserDrewBitmap );
// these days you often need a "byte array". for example,
// to save to parse.com or other cloud services
ByteArrayOutputStream baos = new ByteArrayOutputStream();
whatTheUserDrewBitmap.compress(Bitmap.CompressFormat.PNG, 0, baos);
byte[] yourByteArray;
yourByteArray = baos.toByteArray();
}
Hy vọng nó sẽ giúp ai đó vì điều này đã giúp tôi.
clearDrawing
phương thức của bạn được bao gồm Tôi nhận được ngoại lệ do chiều cao và chiều rộng phải> 0. Tôi đã xem mã và thấy rằng các biến này không được đặt. Vì vậy, tôi đã hỏi bạn làm thế nào để bạn nhận được các giá trị của chiều rộng và chiều cao. PS bạn phải gọi invalidate()
nếu bạn muốn làm mới khu vực vẽ!
Bạn có thể sử dụng lớp này một cách đơn giản:
public class DoodleCanvas extends View{
private Paint mPaint;
private Path mPath;
public DoodleCanvas(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(10);
mPath = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(mPath, mPaint);
super.onDraw(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mPath.moveTo(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
mPath.lineTo(event.getX(), event.getY());
invalidate();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}
hướng dẫn vẽ đường sử dụng lớp Bitmap, Canvas và Paint. draw-line-on-finger-touch và androiddraw
đây là một lớp đơn giản để vẽ đường bằng canvas như hình dưới đây.
public class TestLineView extends View {
private Paint paint;
private PointF startPoint, endPoint;
private boolean isDrawing;
public TestLineView(Context context)
{
super(context);
init();
}
private void init()
{
paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
paint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas)
{
if(isDrawing)
{
canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
startPoint = new PointF(event.getX(), event.getY());
endPoint = new PointF();
isDrawing = true;
break;
case MotionEvent.ACTION_MOVE:
if(isDrawing)
{
endPoint.x = event.getX();
endPoint.y = event.getY();
invalidate();
}
break;
case MotionEvent.ACTION_UP:
if(isDrawing)
{
endPoint.x = event.getX();
endPoint.y = event.getY();
isDrawing = false;
invalidate();
}
break;
default:
break;
}
return true;
}
}
Tôi nghĩ rằng điều quan trọng là phải thêm một điều, nếu bạn sử dụng lạm phát bố cục mà hàm tạo trong drawview không đúng, hãy thêm các hàm tạo này trong lớp:
public DrawingView(Context c, AttributeSet attrs) {
super(c, attrs);
...
}
public DrawingView(Context c, AttributeSet attrs, int defStyle) {
super(c, attrs, defStyle);
...
}
hoặc hệ thống Android không thể thổi phồng tệp bố cục. Tôi hy vọng điều này có thể giúp đỡ.
Ngoài câu trả lời của Ishan, nếu bạn muốn vẽ theo chương trình mà không cần sự tương tác của người dùng, bạn có thể chỉnh sửa lớp một chút như thế này.
public class DrawingCanvas extends View {
private Paint mPaint;
private Path mPath;
private boolean isUserInteractionEnabled = false;
public DrawingCanvas(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(10);
mPath = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(mPath, mPaint);
super.onDraw(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isUserInteractionEnabled) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.moveTo(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
mPath.lineTo(event.getX(), event.getY());
invalidate();
break;
case MotionEvent.ACTION_UP:
break;
}
}
return true;
}
public void moveCursorTo(float x, float y) {
mPath.moveTo(x, y);
}
public void makeLine(float toX, float toY) {
mPath.lineTo(toX, toY);
}
public void setUserInteractionEnabled(boolean userInteractionEnabled) {
isUserInteractionEnabled = userInteractionEnabled;
}
}
Và sau đó sử dụng nó như
drawingCanvas.setUserInteractionEnabled(true) // to enable user interaction
drawingCanvas.setUserInteractionEnabled(true) // to disable user interaction
Để vẽ theo chương trình
drawingCanvas.moveCursorTo(70f, 70f) // Move the cursor (Define starting point)
drawingCanvas.makeLine(200f, 200f) // End point (To where you need to draw)