Issue
On a project I’m working on at my current job, I’ve come across some really pernicious problems where there is either
no good information available or the good information is buried under a sea of bad information.
I’ve kept these issues and, now the issues are resolved, I plan to share a simple example with all developers to get the touch and motion event of finger and draw**
Solution
Follow these steps:
1) Create a view class then extends View, Also create constructor
override the onDraw()
. You add the path of where finger touches and moves. You override the onTouch()
of this purpose. In your onDraw()
you draw the paths using the paint of your choice. You should call invalidate()
to refresh the view.
//drawing path
static Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
static int paintColor = 0xFFFF0000;
//stroke width
private float STROKE_WIDTH = 5f;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
//eraser mode
private boolean erase=false;
//constructor
public DrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
setErase(erase);
}
private void setupDrawing(){
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(STROKE_WIDTH);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
//*************************************** View assigned size ****************************************************
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
public void setErase(boolean isErase){
erase=isErase;
drawPaint = new Paint();
if(erase) {
setupDrawing();
int srcColor= 0x00000000;
PorterDuff.Mode mode = PorterDuff.Mode.CLEAR;
PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(srcColor, mode);
drawPaint.setColorFilter(porterDuffColorFilter);
drawPaint.setColor(srcColor);
drawPaint.setXfermode(new PorterDuffXfermode(mode));
}
else {
setupDrawing();
}
}
//************************************ draw view *************************************************************
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
//*************************** respond to touch interaction **************************************************
@Override
public boolean onTouchEvent(MotionEvent event) {
canvasPaint.setColor(paintColor);
float touchX = event.getX();
float touchY = event.getY();
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
//redraw
invalidate();
return true;
}
//*********************************** return current alpha ***********************************************
public int getPaintAlpha(){
return Math.round((float)STROKE_WIDTH/255*100);
}
//************************************** set alpha ******************************************************
public void setPaintAlpha(int newAlpha){
STROKE_WIDTH=Math.round((float)newAlpha/100*255);
drawPaint.setStrokeWidth(newAlpha);
}
}
2) Your Activity:-
SeekBar mThickness;
private DrawingView mDrawLayout;
Button erase, draw;
private Paint drawPaint = new Paint();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mThickness = (SeekBar) findViewById(R.id.thickness);
mDrawLayout = (DrawingView) findViewById(R.id.viewDraw);
erase = (Button) findViewById(R.id.erase);
draw= (Button) findViewById(R.id.draw);
mDrawLayout.setVisibility(View.VISIBLE);
mDrawLayout.setDrawingCacheEnabled(true);
mDrawLayout.setEnabled(true);
mThickness.setMax(50);
mThickness.setProgress(10);
mDrawLayout.setPaintAlpha(mThickness.getProgress());
int currLevel = mDrawLayout.getPaintAlpha();
mThickness.setProgress(currLevel);
mDrawLayout.invalidate();
erase.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
drawPaint.setColor(Color.TRANSPARENT);
mDrawLayout.setErase(true);
}
});
draw.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mDrawLayout.setErase(false);
}
});
mThickness.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
mDrawLayout.setPaintAlpha(mThickness.getProgress());
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
3) xml:-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".MainActivity" >
<com.example.drawdemo.DrawingView
android:id="@+id/viewDraw"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_marginTop="20dp"
android:scaleType="fitXY" />
<SeekBar
android:id="@+id/thickness"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/viewDraw"
android:layout_marginTop="25dp" />
<Button
android:id="@+id/erase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/thickness"
android:text="erase" />
<Button
android:id="@+id/draw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/erase"
android:text="draw" />
</RelativeLayout>
Answered By - Namrata
Answer Checked By - Katrina (JavaFixing Volunteer)