Reputation: 1746
I am trying to create a rectangle, but this is what happens when I move from starting coordinates towards the end coordinates
, actually I want to show the progress when the user moves from one point to other as well.This is what I would like to have. .
Code:-
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downx = event.getX();
downy = event.getY();
//v.invalidate();
break;
case MotionEvent.ACTION_MOVE:
upx = event.getX();
upy = event.getY();
canvas.drawRect(downx, downy, upx, upy, paint);
}
choosenImageView.invalidate();
break;
case MotionEvent.ACTION_UP:
upx = event.getX();
upy = event.getY();
canvas.drawRect(downx, downy, upx, upy, paint);
}
}
// v.invalidate();
break;
}
return true;
}
Edit What I would like to do is to show the progress i.e. as the user moves his finger, shape should be drawn.
Suggestions/Samples/links anything will be appreciated.
Upvotes: 7
Views: 7736
Reputation: 943
This is Vegers answer converted to Kotlin.
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (startedDrawing) {
canvas.drawRect(startPoint.x, startPoint.y, currentPoint.x, currentPoint.y, mPaint)
}
}
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
startedDrawing = true
startPoint.x = event.x
startPoint.y = event.y
currentPoint.x = event.x
currentPoint.y = event.y
invalidate()
}
MotionEvent.ACTION_MOVE -> {
currentPoint.x = event.x
currentPoint.y = event.y
invalidate()
}
MotionEvent.ACTION_UP -> {
startedDrawing = false
invalidate()
}
}
return true
}
Upvotes: 0
Reputation: 37905
You are directly updating the canvas in the onTouch()
event without clearing it first. This is not the supposed way of drawing something in a View (assuming this is what you want).
Instead you are supposed to store the begin and current coordinates of the rectangle and use them in the onDraw()
event to draw the actual rectangle (after Adnroid cleared the invalidated part of the Canvas for you). Android will issue this event if the canvas needs to be redrawn, so you need to tell that this is required in the onTouch()
event, by using the invalidate()
method:
class myView extends View { // or some other View-based class
boolean drawRectangle = false;
PointF beginCoordinate;
PointF endCoordinate;
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawRectangle = true; // Start drawing the rectangle
beginCoordinate.x = event.getX();
beginCoordinate.y = event.getY();
endCoordinate.x = event.getX();
endCoordinate.y = event.getY();
invalidate(); // Tell View that the canvas needs to be redrawn
break;
case MotionEvent.ACTION_MOVE:
endCoordinate.x = event.getX();
endCoordinate.y = event.getY();
invalidate(); // Tell View that the canvas needs to be redrawn
break;
case MotionEvent.ACTION_UP:
// Do something with the beginCoordinate and endCoordinate, like creating the 'final' object
drawRectangle = false; // Stop drawing the rectangle
invalidate(); // Tell View that the canvas needs to be redrawn
break;
}
return true;
}
protected void onDraw(Canvas canvas) {
if(drawRectangle) {
// Note: I assume you have the paint object defined in your class
canvas.drawRect(beginCoordinate.x, beginCoordinate.y, endCoordinate.x, endCoordinate.y, paint);
}
}
}
Upvotes: 9
Reputation: 2927
Sorry Dear i give you whole activity witch i use and draw rect on canvas.
public class CanvasExample extends Activity
{
/** Called when the activity is first created. */
RelativeLayout relMainOperationLayout;
RelativeLayout relTabHeader;
//RelativeLayout relMidalLayout;
RelativeLayout relBelowLayout;
Context myContext;
DrawCanvas drawCanvas;
static boolean loadFlage=true;
BibleHelper bibleHelper;
Bitmap mainBitmap;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
myContext=CanvasExample.this;
bibleHelper=new BibleHelper(CanvasExample.this,myContext);
bibleHelper.setFullScreen();
LayoutInflater layoutInflater=(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int layoutId = myContext.getResources().getIdentifier("main","layout",getPackageName());
relMainOperationLayout = (RelativeLayout) layoutInflater.inflate(layoutId,null);
relTabHeader=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relHeadLayout);
//relMidalLayout=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relmidalLayout);
relBelowLayout=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relBelowLayout);
mainBitmap=getIconDrawable(R.drawable.splash);
drawCanvas=new DrawCanvas(CanvasExample.this,myContext);
//drawCanvas.setBackgroundColor(Color.YELLOW);
//drawCanvas.setBackgroundDrawable(CanvasExample.this.getResources().getDrawable(R.drawable.splash));
drawCanvas.setBackgroundDrawable(new BitmapDrawable(mainBitmap));
RelativeLayout.LayoutParams drawParams=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
drawParams.addRule(RelativeLayout.BELOW, relTabHeader.getId());
//relMidalLayout.addView(drawCanvas,drawParams);
relMainOperationLayout.addView(drawCanvas,drawParams);
// mainImageView=new ImageView(CanvasExample.this);
//
// RelativeLayout.LayoutParams mainParams=new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,200);
// relMainOperationLayout.addView(mainImageView,mainParams);
// mainImageView.setBackgroundDrawable(CanvasExample.this.getResources().getDrawable(R.drawable.ic_launcher));
setContentView(relMainOperationLayout);
}
class DrawCanvas extends View
{
Context drawContext;
Activity drawActivity;
ImageView image;
Paint mPaint;
int left=0,right=0,top=0,bottom=0;
Canvas passCanvas;
//Bitmap bitmapOrg;
// bitmapOrg;
public DrawCanvas(Activity activity,Context context)
{
super(activity);
this.drawActivity=activity;
this.drawContext=context;
//bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.splash);
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
mPaint.setFilterBitmap(true);
this.setOnTouchListener(new View.OnTouchListener() {
//@Override
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
invalidate();
left=(int) event.getX();
right=left+1;
top=(int) event.getY();
bottom=top+1;
mPaint.setColor(Color.BLACK);
onDraw(passCanvas=new Canvas());
break;
case MotionEvent.ACTION_MOVE:
invalidate();
int tempX=(int) event.getX();
//System.err.println("Get X->"+event.getX());
if(tempX>right)
{
right=right+1;
}
else
{
right=right-1;
}
//System.err.println("Get Y->"+event.getY());
int tempY=(int) event.getY();
if(tempY>bottom)
{
bottom=bottom+1;
}else
{
bottom=bottom-1;
}
mPaint.setColor(Color.GREEN);
onDraw(passCanvas=new Canvas());
break;
case MotionEvent.ACTION_UP:
invalidate();
mPaint.setColor(Color.RED);
onDraw(passCanvas=new Canvas());
System.err.println("After Touch Up");
CanvasExample.loadFlage=false;
onDraw(passCanvas=new Canvas());
/*
bibleHelper.showErrorLog("Start X -->"+left);
bibleHelper.showErrorLog("Real X -->"+event.getX());
bibleHelper.showErrorLog("End X-->"+right);
bibleHelper.showErrorLog("Start Y-->"+top);
bibleHelper.showErrorLog("Real Y-->"+top);
bibleHelper.showErrorLog("End Y-->"+bottom);
*/
Bitmap croppedBmp = Bitmap.createBitmap(mainBitmap,left,top,right,bottom);
final Dialog dialog = new Dialog(CanvasExample.this);
dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Title...");
dialog.setCancelable(true);
ImageView image = (ImageView) dialog.findViewById(R.id.main);
image.setImageBitmap(croppedBmp);
Button btnClose=(Button) dialog.findViewById(R.id.btnClose);
btnClose.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
dialog.dismiss();
}
});
dialog.show();
break;
default:
break;
}
return true;
}
});
}
@Override
protected void onDraw(Canvas canvas)
{
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
private Bitmap getIconDrawable(int imageId)
{
//Drawable rtnDrawable = null;
Bitmap imageBitmap=null;
try
{
int getImageWH[];
imageBitmap = BitmapFactory.decodeResource(getResources(),imageId);
int IW = imageBitmap.getWidth();
int IH = imageBitmap.getHeight();
bibleHelper.showErrorLog("Icon Width->" + IW);
bibleHelper.showErrorLog("Icon Height->" + IH);
WindowManager winManager = (WindowManager) CanvasExample.this.getSystemService(Context.WINDOW_SERVICE);
int screenwidth = winManager.getDefaultDisplay().getWidth();
int screenheight = winManager.getDefaultDisplay().getHeight();
getImageWH = bibleHelper.getObjectWidthHeight(screenwidth,screenheight, IW, IH);
bibleHelper.showErrorLog("Get Icon Width->" + getImageWH[0]);
bibleHelper.showErrorLog("Get Icon Height->" + getImageWH[1]);
imageBitmap = Bitmap.createScaledBitmap(imageBitmap, getImageWH[0],getImageWH[1], false);
bibleHelper.showErrorLog("New Width-->"+imageBitmap.getWidth());
bibleHelper.showErrorLog("New Height-->"+imageBitmap.getHeight());
//rtnDrawable = (Drawable) new BitmapDrawable(imageBitmap);
} catch (Exception ex) {
bibleHelper.showErrorLog("Convert Icon Exception-->"+ ex.toString());
}
//return rtnDrawable;
return imageBitmap;
}
}
In this BibleHelper is Helper class witch use for display some message and log .
Upvotes: 3
Reputation: 4556
If I understand you correct you want the user to draw the rectangle on the screen and you would then draw it on the display.
I think you could just paint a point where the user presses, just to give a feedback to the user, and when he finishes drawing you substitute by the rectangle
Or draw the lines of the rectangle, so user starts drawing and you have a line from the start to his finger, when user changes direction you start a new line from where the user changed direction and the finger, then when the user returns to start you have a rectangle draw as 4 lines
Upvotes: 2
Reputation: 619
Do you clean the canvas between two rectangle ? Add a function like this one :
void clearCanvas()
{
canvas.drawRect(0,0, width, height, paint);
}
Upvotes: 6
Reputation: 6881
case MotionEvent.ACTION_MOVE:
upx = event.getX();
upy = event.getY();
canvas.drawRect(downx, downy, upx, upy, paint);
}
choosenImageView.invalidate();
break;
This code is causing it. Because you are creating many rectangles here. Instead, in onDraw(Canvas canvas)
have drawRect method and use invalidate on all events. Hope this helps.
Upvotes: 3