I am pretty new to Android so I apologize ahead of time if I am missing something, but my problem is that I am trying to draw a circle at a certain location everytime I click on the screen.
I have tried logging and it does return an int where it matches my if statement but nothing gets drawn.
public boolean onTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
drawCirc = true;
xTouch = event.getX();
Log.d("keyboard", "xpos" + xTouch);
yTouch = event.getY();
break;
case MotionEvent.ACTION_UP:
drawCirc = false;
}
return true;
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
if(drawCirc) {
if (xTouch < 150 && xTouch>0) {
paint.setColor(Color.RED);
canvas.drawCircle(150, 500, 100, paint);
isPlayer1 = false;
invalidate();
}
}
}
#Javanator is right, you should do invalidate in touch listener.
Meanwhile, you can try out the code below, which adds animation when circle being drawn.
Paint paint = new Paint();
{
paint.setColor(Color.RED);
}
// The radius of the circle you want to draw
// 0 by default
private int radius = 0;
// The animator to animate circle drawing
private ObjectAnimator radiusAnimator;
public void setRadius(int newRadius) {
this.radius = newRadius;
this.invalidate();
}
private void showCircle(boolean show) {
ObjectAnimator animator = this.getRadiusAnimator();
if (show) {
animator.start();
} else {
animator.reverse();
}
}
private ObjectAnimator getRadiusAnimator() {
if (this.radiusAnimator == null) {
this.radiusAnimator = ObjectAnimator.ofInt(this, "radius", 0, 100);
}
return this.radiusAnimator;
}
public boolean onTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
// drawCirc = true;
xTouch = event.getX();
Log.d("keyboard", "xpos" + xTouch);
yTouch = event.getY();
showCircle(true);
break;
case MotionEvent.ACTION_UP:
// drawCirc = false;
showCircle(false);
}
return true;
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (xTouch < 150 && xTouch > 0) {
canvas.drawCircle(xTouch, yTouch, radius, paint);
}
/*
if(drawCirc) {
if (xTouch < 150 && xTouch>0) {
paint.setColor(Color.RED);
canvas.drawCircle(150, 500, 100, paint);
isPlayer1 = false;
invalidate();
*/
}
public class CustomView extends View {
boolean drawCirc;
float xTouch;
boolean isPlayer1;
float yTouch;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
drawCirc=true;
xTouch = event.getX();
yTouch = event.getY();
invalidate();
}
return false;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
if (drawCirc) {
paint.setColor(Color.RED);
canvas.drawCircle(xTouch, yTouch, 100, paint);
isPlayer1 = false;
invalidate();
}
}}
I have solved your functionality and Implemented sample code. I have checked it and it's working and you have not put a code in onTouch Listener that's why it's not worked but now I have solved. if you want area limit then put yourif (xTouch < 150 && xTouch>0)
Related
How to draw a circler path by swiping, it's draw with edges.
I wanted to draw path with smooth edges.
this is my code.
this.mPaint = new Paint();
this.mPaint.setStyle(Paint.Style.STROKE);
this.mPaint.setStrokeWidth(getResources().getDimensionPixelSize(R.dimen._5sdp));
this.mPaint.setStrokeCap(Paint.Cap.ROUND);
this.mPaint.setStrokeJoin(Paint.Join.ROUND);
this.mPaint.setColor(Color.BLUE);
this.mPaint.setAntiAlias(true);
this.mPaint.setDither(true);
this code is in OnTouchListener
public boolean onTouch(View view, MotionEvent motionEvent) {
int action = motionEvent.getAction();
float x = motionEvent.getX();
float y = motionEvent.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
mPath.reset();
mPath.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "onT:-> x " + x + " y-> " + y);
mPath.lineTo(x, y);
view.invalidate();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mPaths.add(new CurrentDraw(mPath, mPaint));
mPath.reset();
view.invalidate();
// updateLocalSS();
return false;
}
return true;
}
this code is in ondraw() method
if (mPaths != null) {
for (int i = 0; i < mPaths.size(); i++) {
canvas.drawPath(mPaths.get(i).path, mPaths.get(i).paint);
}
}
if (mPath != null) {
canvas.drawPath(mPath, mPaint);
}
Please just try this way may help you
RectF area;
private Paint bgPaint;
private Paint initpaint() {
int bColor = Color.WHITE;
if (!isInEditMode()) {
bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
} else {
bgPaint = new Paint();
}
bgPaint.setColor(bColor);
bgPaint.setStyle(Paint.Style.STROKE);
bgPaint.setStrokeWidth(sizeBg);
}
Public void initArea(){
float drawPadding = (size / 2);
float width = getWidth();
float height = getHeight();
float left = drawPadding;
float top = drawPadding;
float right = width - drawPadding;
float bottom = height - drawPadding;
area = new RectF(left, top, right, bottom);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Path path = new Path();
path.addCircle(area.centerX(), area.centerY(), getRadius(), Path.Direction.CCW);
canvas.drawPath(path, bgPaint);
}
private float getRadius() {
if (area != null) {
return (area.width() / 2);
} else {
return 0;
}
}
I am working on an application which captures an applicant's signature and saves it to the phone memory. The class used for the signature view is given below
public class SignatureView extends View {
private static final float STROKE_WIDTH = 5f;
/** Need to track this so the dirty region can accommodate the stroke. **/
private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
private Paint paint = new Paint();
private Path path = new Path();
/**
* Optimizes painting by invalidating the smallest possible area.
*/
private float lastTouchX;
private float lastTouchY;
private final RectF dirtyRect = new RectF();
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
}
/**
* Erases the signature.
*/
public void clear() {
path.reset();
// Repaints the entire view.
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawARGB(255, 233, 255, 255);
canvas.drawPath(path, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(eventX, eventY);
lastTouchX = eventX;
lastTouchY = eventY;
// There is no end point yet, so don't waste cycles invalidating.
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
// Start tracking the dirty region.
resetDirtyRect(eventX, eventY);
// When the hardware tracks events faster than they are delivered, the
// event will contain a history of those skipped points.
int historySize = event.getHistorySize();
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
path.lineTo(historicalX, historicalY);
}
// After replaying history, connect the line to the touch point.
path.lineTo(eventX, eventY);
break;
default:
//debug("Ignored touch event: " + event.toString());
return false;
}
// Include half the stroke width to avoid clipping.
invalidate(
(int) (dirtyRect.left - HALF_STROKE_WIDTH),
(int) (dirtyRect.top - HALF_STROKE_WIDTH),
(int) (dirtyRect.right + HALF_STROKE_WIDTH),
(int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
lastTouchX = eventX;
lastTouchY = eventY;
return true;
}
/**
* Called when replaying history to ensure the dirty region includes all
* points.
*/
private void expandDirtyRect(float historicalX, float historicalY) {
if (historicalX < dirtyRect.left) {
dirtyRect.left = historicalX;
} else if (historicalX > dirtyRect.right) {
dirtyRect.right = historicalX;
}
if (historicalY < dirtyRect.top) {
dirtyRect.top = historicalY;
} else if (historicalY > dirtyRect.bottom) {
dirtyRect.bottom = historicalY;
}
}
/**
* Resets the dirty region when the motion event occurs.
*/
private void resetDirtyRect(float eventX, float eventY) {
// The lastTouchX and lastTouchY were set when the ACTION_DOWN
// motion event occurred.
dirtyRect.left = Math.min(lastTouchX, eventX);
dirtyRect.right = Math.max(lastTouchX, eventX);
dirtyRect.top = Math.min(lastTouchY, eventY);
dirtyRect.bottom = Math.max(lastTouchY, eventY);
}
// get drawn image as bitmap
public Bitmap getBitmap() {
this.setDrawingCacheEnabled(true);
this.buildDrawingCache();
Bitmap bmp = Bitmap.createBitmap(this.getDrawingCache());
this.setDrawingCacheEnabled(false);
return bmp;
}
public boolean isDrawn(){
return ! path.isEmpty();
}
}
This class returns the signature bitmap.This view works fine for devices with Android 8.0 and below, but its not working for Android 8.0 plus devices. For Devices above Android 8.0, the method getBitmap() returns a bitmap of the signature, but for Devices above Android 8.0, it returns empty.
Another Solution I tried which did not work either
public class SignatureViewType3 extends View {
private Bitmap _Bitmap;
private Canvas _Canvas;
private Path _Path;
private Paint _BitmapPaint;
private Paint _paint;
private float _mX;
private float _mY;
private float TouchTolerance = 4;
private float LineThickness = 4;
private boolean signatureAdded;
public SignatureViewType3(Context context, AttributeSet attr) {
super(context, attr);
_Path = new Path();
_BitmapPaint = new Paint(Paint.DITHER_FLAG);
_paint = new Paint();
_paint.setAntiAlias(true);
_paint.setDither(true);
_paint.setColor(Color.argb(255, 0, 0, 0));
_paint.setStyle(Paint.Style.STROKE);
_paint.setStrokeJoin(Paint.Join.ROUND);
_paint.setStrokeCap(Paint.Cap.ROUND);
_paint.setStrokeWidth(LineThickness);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
_Bitmap = Bitmap.createBitmap(w, (h > 0 ? h : ((View) this.getParent()).getHeight()), Bitmap.Config.ARGB_8888);
_Canvas = new Canvas(_Bitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
getParent().requestDisallowInterceptTouchEvent(true);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(_Bitmap, 0, 0, _BitmapPaint);
canvas.drawPath(_Path, _paint);
}
private void TouchStart(float x, float y) {
_Path.reset();
_Path.moveTo(x, y);
_mX = x;
_mY = y;
}
private void TouchMove(float x, float y) {
float dx = Math.abs(x - _mX);
float dy = Math.abs(y - _mY);
if (dx >= TouchTolerance || dy >= TouchTolerance) {
_Path.quadTo(_mX, _mY, (x + _mX) / 2, (y + _mY) / 2);
_mX = x;
_mY = y;
}
}
private void TouchUp() {
if (!_Path.isEmpty()) {
_Path.lineTo(_mX, _mY);
_Canvas.drawPath(_Path, _paint);
} else {
_Canvas.drawPoint(_mX, _mY, _paint);
}
signatureAdded = true;
_Path.reset();
}
#Override
public boolean onTouchEvent(MotionEvent e) {
super.onTouchEvent(e);
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
TouchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
TouchMove(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
TouchUp();
invalidate();
break;
}
return true;
}
public void clear() {
_Canvas.drawColor(Color.WHITE);
invalidate();
}
public byte[] getBytes() {
Bitmap b = getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 100, baos);
if(signatureAdded)
return baos.toByteArray();
else
return null;
}
public Bitmap getBitmap() {
View v = (View) this.getParent();
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
v.draw(c);
return b;
}
public boolean isDrawn(){
// return ! _Path.isEmpty();
return true;
}
}
getDrawingCache() is deprecated in Android API 28, so you should use Canvas like in this answer of Ashvin solanki
RelativeLayout view = (RelativeLayout)findViewById(R.id.relativelayout);
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
bgDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
or PixelCopy like in that article of Shivesh Karan Mehta:
// for api level 28
fun getScreenShotFromView(view: View, activity: Activity, callback: (Bitmap) -> Unit) {
activity.window?.let { window ->
val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
val locationOfViewInWindow = IntArray(2)
view.getLocationInWindow(locationOfViewInWindow)
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
PixelCopy.request(
window,
Rect(
locationOfViewInWindow[0],
locationOfViewInWindow[1],
locationOfViewInWindow[0] + view.width,
locationOfViewInWindow[1] + view.height
), bitmap, { copyResult ->
if (copyResult == PixelCopy.SUCCESS) {
callback(bitmap) }
else {
}
// possible to handle other result codes ...
},
Handler()
)
}
} catch (e: IllegalArgumentException) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
e.printStackTrace()
}
}
}
If I draw with Rectangle line and after that I want to draw with dash line my rectangle line will be transformed in dash line. I use this code:
This is MyLine.java
public class MyLine { // line
public float x,y;
public float xStart,yStart,xEnd,yEnd;
public Paint paint = new Paint();
Path path = new Path();
public MyLine()
{
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(new DashPathEffect(new float[]{20,30}, 0));
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5f);
path = new Path();
}
public void mouseDown(Path path,float xDown,float yDown){
path.moveTo(xDown, yDown);
path.lineTo(xDown, yDown);
xStart = xDown;
yStart = yDown;
}
public void mouseUp(Path path,float xUp,float yUp){
path.lineTo(xUp, yUp);
xEnd = xUp;
yEnd = yUp;
}
public void draw(Canvas c){
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(new DashPathEffect(new float[]{10,20}, 0));
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5f);
path = new Path();
c.drawLine(xStart,yStart,xEnd,yEnd,paint);
}
public void changeColor(int color){
paint = new Paint(paint);
paint.setColor(color);
//myPaint.setColor(color);
}
}
Here is some code from CanvasView.java where I think is problem.
public void setDashLine(){
dashedLine = true;
paint = new Paint();
paint.setPathEffect(dashEffect);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
myCanvas = new Canvas();
path = new Path();
}
public void setNormalLine(){
paint.setColor(Color.RED);
paint = new Paint();
paint.setPathEffect(null);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(null);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
myCanvas = new Canvas();
path = new Path();
}
protected void onDraw(Canvas canvas) {
paint.setPathEffect(null);
if(bitmap!=null){
canvas.drawBitmap(bitmap, 0, 0, paint);
for(MyCircle circle:circleList){// draw circles
myCanvas.drawCircle(getCircleMidPointX(circle.firstX, circle.lastX),getCircleMidPointY(circle.firstY, circle.lastY),circle.radius,myPaint);
}
}
for(MyLine line:lineList){ //draw lines
if(dashedLine)
line.paint.setPathEffect(dashEffect);
else
line.paint.setPathEffect(null);
canvas.drawLine(line.xStart, line.yStart, line.xEnd, line.yEnd, line.paint);
}
final OnTouchListener drawLineListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
undonePaths.clear();
path.reset();
myLine = new MyLine();
myLine.xStart = event.getX();
myLine.yStart = event.getY();
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
myLine.xEnd = event.getX();
myLine.yEnd = event.getY();
invalidate();
lineList.add(myLine);
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
final OnTouchListener drawDashedLineListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
myLine = new MyLine();
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
invalidate();
lineList.add(myLine);
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
If you can see something where is wrong please tell me how can make to be useful.
I want to erase my bitmap but I don't want to erase background image. When I try to erase is white and it draw very hard in frames.
This is from CanvasView
erasePaint.setColor(Color.WHITE);
//erasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
erasePaint.setAntiAlias(true);
erasePaint.setStyle(Paint.Style.STROKE);
erasePaint.setStrokeJoin(Paint.Join.ROUND);
erasePaint.setStrokeWidth(12);
//....
protected void onDraw(Canvas canvas) {
paint.setPathEffect(null);
if(bitmap!=null){
for(MyEraser e:eraserList){
canvas.drawPath(e.p,erasePaint);
invalidate();
}
final OnTouchListener eraseListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// erasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
//FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
myEraser = new MyEraser();
lastTouchX = event.getX();
lastTouchY = event.getY();
myEraser.mouseDown(event.getX(), event.getY());
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
resetDirtyRect(event.getX(),event.getY());
int historySize = event.getHistorySize();
for(int i=0;i<historySize;i++){
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
myEraser.mouseUp(historicalX, historicalY);
}
myEraser.mouseUp(event.getX(), event.getY());
eraserList.add(myEraser);
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
invalidate(
(int) (dirtyRect.left - HALF_STROKE_WIDTH),
(int) (dirtyRect.top - HALF_STROKE_WIDTH),
(int) (dirtyRect.right + HALF_STROKE_WIDTH),
(int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
lastTouchX = event.getX();
lastTouchY = event.getY();
return true;
}
};
}
}
This is MyEraser
public class MyEraser {
Paint paint = new Paint();
Path p = new Path();
public MyEraser(){
paint.setColor(Color.WHITE);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5);
}
public void mouseDown(float x, float y) {
//path.addCircle(x,y,5,Path.Direction.CW);
p.moveTo( x, y );
// path.lineTo(x, y);
}
public void mouseMove(Path path, float x, float y) {
// path.addCircle(x,y,5,Path.Direction.CW);
}
public void mouseUp(float x, float y){
//path.addCircle(x,y,5,Path.Direction.CW);
p.lineTo(x, y);
}
public void draw(Canvas c,Path path){
//paint.setColor(Color.WHITE);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(7);
c.drawPath(p, paint);
}
}
EDIT: Started over for better explanation :)
I am not familiar with Android, in fact I have never used it. Use this code as an example of how to organize your code, rather than a functional code.
class MyView extends View {
private Eraser myEraser;
private Bitmap myBackgroundImage;
private Canvas myForegroundCanvas;
public MyView(Context context, Attributes, attrs) {
myEraser = new Eraser()
myBackgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.your_background_name);
Bitmap image = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); // the width and height of the view
myForegroundCanvas = new Canvas(image);
}
public boolean onTouchEvent(MotionEvent event) {
// update your eraser path
return true;
}
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(myBackgroundImage, 0, 0, null);
//for (Eraser item : eraserList) {
// if you have multiple eraser, add them to a list
myEraser.draw(myForegroundCanvas);
//}
canvas.drawCanvas(myForegroundCanvas, 0, 0, null);
}
}
The main idea is to keep the separation between your background and foreground images. That way, you could easily change the background and it would be updated. You could also have a reset on the foreground to erase everything, etc.
I hope this helps you.
I edited MyLine and CanvasView but now I draw normal line and dashed line but after that I click on normal line and it draw dashed line. Down you have mt edited code. After I created private paint in MyLine, line.paint from onDraw was transformed in getPaint
Here you have MyLine.java
public class MyLine { // line
public float x,y;
public float xStart,yStart,xEnd,yEnd;
private boolean drawDashed;
private Paint paint = new Paint();
public MyLine(boolean drawDashed)
{
if(drawDashed){
getPaint().setColor(Color.BLUE);
getPaint().setStyle(Paint.Style.STROKE);
getPaint().setPathEffect(new DashPathEffect(new float[]{20,30}, 0));
getPaint().setAntiAlias(true);
getPaint().setStrokeJoin(Paint.Join.ROUND);
getPaint().setStrokeWidth(5f);
} else{
getPaint().setColor(Color.RED);
getPaint().setStyle(Paint.Style.STROKE);
getPaint().setPathEffect(null);
getPaint().setAntiAlias(true);
getPaint().setStrokeJoin(Paint.Join.ROUND);
getPaint().setStrokeWidth(5f);
}
}
public void mouseDown(Path path,float xDown,float yDown){
//path.moveTo(xDown, yDown);
// path.lineTo(xDown, yDown);
xStart = xDown;
yStart = yDown;
}
public void mouseUp(Path path,float xUp,float yUp){
//path.lineTo(xUp, yUp);
xEnd = xUp;
yEnd = yUp;
}
public void draw(Canvas c){
getPaint().setColor(Color.GREEN);
//paint.setStyle(Paint.Style.STROKE);
getPaint().setPathEffect(new DashPathEffect(new float[]{10,20}, 0));
getPaint().setAntiAlias(true);
getPaint().setStrokeJoin(Paint.Join.ROUND);
getPaint().setStrokeWidth(5f);
c.drawLine(xStart,yStart,xEnd,yEnd,getPaint());
}
public Paint getPaint() {
return paint;
}
public void setPaint(Paint paint) {
this.paint = paint;
}
Here is from CanvasView.java
protected void onDraw(Canvas canvas) {
paint.setPathEffect(null);
if(bitmap!=null){
canvas.drawBitmap(bitmap, 0, 0, paint);
for(MyCircle circle:circleList){// draw circles
myCanvas.drawCircle(getCircleMidPointX(circle.firstX, circle.lastX),getCircleMidPointY(circle.firstY, circle.lastY),circle.radius,myPaint);
}
}
for (Path p : paths){
canvas.drawPath(p, paint);
}
canvas.drawPath(path, paint);
for(MyLine line:lineList){ //draw lines
canvas.drawLine(line.xStart, line.yStart, line.xEnd, line.yEnd, line.getPaint());
}
final OnTouchListener drawLineListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
myLine = new MyLine(dashedLine);
myLine.xStart = event.getX();
myLine.yStart = event.getY();
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
myLine.xEnd = event.getX();
myLine.yEnd = event.getY();
invalidate();
lineList.add(myLine);
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
final OnTouchListener drawDashedLineListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
b in onDraw()
if(dashedLine)
line.paint.setPathEffect(dashEffect);
else
line.paint.setPathEffect(null);
You are resetting the effect for all lines, so that is what is being drawn: all dashed or all normal
What you probaly want to do is give each MyLine its own property:
boolean drawDashed =true/false;
And let it draw itself accordingly (picking the right paint with the right dasheffect)
public class MyLine { // line
public float x,y;
public float xStart,yStart,xEnd,yEnd;
private boolean drawDashed;
private Paint paint = new Paint();
public MyLine(boolean drawDashed)
{
if(drawDashed){
...
paint.setPathEffect(new DashPathEffect(new float[]{10,20}, 0));
....
} else{
....
paint.setPathEffect(null);
...
}
}
public void mouseDown(Path path,float xDown,float yDown){
//path.moveTo(xDown, yDown);
// path.lineTo(xDown, yDown);
xStart = xDown;
yStart = yDown;
}
public void mouseUp(Path path,float xUp,float yUp){
//path.lineTo(xUp, yUp);
xEnd = xUp;
yEnd = yUp;
}
public void draw(Canvas c){
c.drawLine(xStart,yStart,xEnd,yEnd,paint);
}
}
So add two private properties to Myline so the line it self has the knowledge how to draw itself:
private boolean drawDashed;
private Paint paint = new Paint();
then the draw method becomes very simple:
public void draw(Canvas c){
c.drawLine(xStart,yStart,xEnd,yEnd,paint);
}