Draw circle where user touches screen - java

I draw a circle where the user touches a image view. It draws the circle fine, but it is not where the user touches. It is always off the left by a lot. Here is the code:
getting the touch:
image.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
System.out.println("Touch recieved at "+arg1.getX() + " " + arg1.getY());
touchX = (arg1.getX());
touchY = (arg1.getY());
System.out.println("Touch recieved at "+touchX + " " + touchY);
image.setImageBitmap(createImage());
return true;
}
});
and drawing on the image:
public Bitmap createImage(){
Bitmap image = bmp.copy(Bitmap.Config.RGB_565, true);
Canvas canvas = new Canvas(image);
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
canvas.drawCircle(touchX, touchY, radius, paint);
System.out.println("Drew a circle at "+touchX+" " + touchY+" with a radius of "+radius+".");
return image;
}
Any ideas?

Try to draw at
touchX=touchX- image.getWidth() / 2;
touchY=touchY- image.getHeight() / 2;
this will draw the center of the image the place you touch

You have to add touch listener to the layout not to the image. Add setOnTouchListener to the layout. No need of touch listener to the image.

Related

Android Studio SVG Image has rectangle box behind it

I have an SVG image and I have it set up so when I move my finger over the image it tells me that I've "entered an image". But I noticed that there's an invisible box shape around the image, so when my finger is a bit outside the image I still get the "entered image" message. I want to only have it so if I go in the image it will display the message.
How do you remove that invisible box so the only thing my MotionEvent registers is the exact shape of my svg ?
My code:
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
rect1= new Rect(dragon.getLeft(), dragon.getTop(),
dragon.getRight(), dragon.getBottom());
rect2= new Rect(buttonTwo.getLeft(), buttonTwo.getTop(),
buttonTwo.getRight(), buttonTwo.getBottom());
}
///////////////////////////////////////////////
if (event.getActionMasked() == (MotionEvent.ACTION_DOWN | MotionEvent.ACTION_MOVE)) {
if (rect1.contains((int) event.getX(), (int) event.getY())) {
System.out.println(" Dragon Entered ");
}
}
if (event.getActionMasked() == (MotionEvent.ACTION_DOWN | MotionEvent.ACTION_MOVE)) {
if (rect2.contains((int) event.getX(), (int) event.getY())) {
System.out.println(" in button2!!!!: ");
}
}

Android saving coordinates canvas Drawcircle and display on Different Devices

class Draw extends View {
private Paint mPaint;
public Button mCircles;
DrawFragment mDrawFragment;
private Circle mCurrentCircle;
private List<Circle> mCircle= new ArrayList<>();
public Draw(Context context){
this(context,null);
}
public Draw(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint=new Paint();
mPaint.setColor(Color.RED);
mPaint.setAlpha(80);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Circle circle : mCircle) {
float x1 = circle.getCenter().x;
float x2 = circle.getFinal().x;
float y1 = circle.getCenter().y;
float y2 = circle.getFinal().y;
double radius = Math.sqrt(Math.pow(dpx1 - dpx2, 2) + Math.pow(dpy1 - dpy2, 2));
float rad = (float) radius;
canvas.drawCircle(dpx1, dpy1, rad, mPaint);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mCurrentCircle = new Circle(current);
mCircle.add(mCurrentCircle);
break;
case MotionEvent.ACTION_MOVE:
if (mCurrentCircle != null) {
mCurrentCircle.setFinal(current);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
mCurrentCircle = null;
invalidate(); break;
}
}
Log.i(TAG, "onTouchEvent: at x="+current.x + ", y =" + current.y);
return true;
}
1.I'm saving these coordinates of circles drawn on canvas and this is to mark damages on a car.
but when i use these values to display on a bigger device , Circle positions are not intact .. what can be done?
All the coordinates are referenced to a device with a screen determined by pixels and pixels per inches.
If you wish to use the same information on a different device, you must set a sort of anchor point which works for you as a reference.
For example, if those circles will be drawn over a background image of a car, you should be able to reference theme to the position of that picture.
With that information, on any other device, you should be able to redraw those circles on any device based on the fact the coordinates are not referenced to the device but are reference to the car image.
I hope this help you to re think the problem.

Draw Component in Canvas Without draw already drawed component again

I try to draw bitmap in touch points when touch move i need to draw the bitmap in newly added position not redraw the whole points again how to achieve that.
i try the following
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:{
break;
}
case MotionEvent.ACTION_MOVE:{
drawPanel.setPaths(new PointF(event.getX(),event.getY()));
drawPanel.invalidate();
break;
}
case MotionEvent.ACTION_UP:{
break;
}
}
return true;
}
And
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);Z
if(point != null) {
for (PointF pointF : points)
canvas.drawBitmap(shape, pointF.x, pointF.y, paint);
}
}
i know its draw again the loop. I need continue to draw the newly position only how to do that?
onDraw needs to draw the entire view. So there is no way to draw only the new touches in onDraw.
What you can do is create a memory bitmap, and draw new touches to the bitmap in onTouch. Then draw the bitmap to the screen in onDraw. Since the bitmap will never be cleared, you only have to add touches to it.

Canvas; How to remove shapes retroactively

So I am using onDraw in a custom View class to draw shapes on a RelativeLayout + TableLayout all that works fine, and I have another class that I use to draw lines from Point A to Point B etc. example below:
My Goal:
If I drag my finger from Point A (objectA) to Point B(objectB), how can I delete those 2 View Objects from the canvas? I added a method:
objectA.delete();
objectB.delete();
that should delete both A and B when I drag my finger through MotionEvent, but it only deletes one and not the other, so i am thinking it's not retroactive?
Codes below:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
/// get the child that corresponds to the first touch
DotView objectA = getChildForTouch((TableLayout) v, x, y);
return true;
case MotionEvent.ACTION_MOVE:
///used the x - y to get the object for every other shape the user`S finger passes over.
DotView objectB = getChildForTouch((TableLayout) v, x, y);
/// just update positions
line.setCoords(mStartX, mStartY, (int) x, (int) y);
objectA.delete(); ///Delete first shape
objectB.delete(); ///Delete second shape
break;
case MotionEvent.ACTION_UP:
///Gets the last shape where the user released their fingers
endView = getChildForTouch((TableLayout) v, x, y);
break;
Delete method inside the: DotView extends View class:
private static class DotView extends View {
private static final int DEFAULT_SIZE = 100;
private Paint mPaint = new Paint();
private Rect mBorderRect = new Rect();
private Paint mCirclePaint = new Paint();
private int mRadius = DEFAULT_SIZE / 4;
public DotView(Context context) {
super(context);
mPaint.setStrokeWidth(2.0f);
mPaint.setStyle(Style.STROKE);
mPaint.setColor(Color.RED);
mCirclePaint.setColor(Color.CYAN);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.parseColor("#0099cc"));
mBorderRect.left = 0;
mBorderRect.top = 0;
mBorderRect.right = getMeasuredWidth();
mBorderRect.bottom = getMeasuredHeight();
canvas.drawRect(mBorderRect, mPaint);
canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2,
mRadius, mCirclePaint);
}
public void delete(){
mPaint.setColor(Color.TRANSPARENT);
}
}
Just something simple to fake delete the circles
Thanks in advance guys.. more codes can be provided if need be.
Edit: If I can accomplish this in any other way please feel free to share. (Draw circles on a Grid and delete the ones I used my finger to draw my line over)
First of all try changing your delete() method to this:
public void delete(){
mPaint.setColor(Color.TRANSPARENT);
invalidate();
}
You need to let your View know that you want it to redraw itself (that's why the invalidate() call).

How to add a view to a specifc point on mapView

an When an onTouch event occurs on my MapView, i want layout i have specified to be drawn above the where the user has touched
The below is where i have started, i do not know how to actually place the popup view on the x and y values retrieved from the event. Do you guys have any ideas?
#Override
public boolean onTouchEvent(MotionEvent ev, MapView mapView) {
int X = (int)ev.getX();
int Y = (int)ev.getY();
ViewGroup parent=(ViewGroup)map.getParent();
View popup=getLayoutInflater().inflate(R.id.popup, parent, false);
((ViewGroup)map.getParent()).addView(popup);
You can set the MapView.LayoutParams() with the values of x and y and then call the MapView's addView with the LayoutParams.
MapView.LayoutParams params = new MapView.LayoutParams(width, height, x, y, alignment);
mapView.addView(popup, params);
At first, your need one global Point with your X,Y coordinates
#Override
public boolean onTouchEvent(MotionEvent ev, MapView mapView) {
int X = (int)ev.getX();
int Y = (int)ev.getY();
selectedPoint = new Point(X,Y);
return true;
}
Now, you should override the onDraw() method to draw you popup view. There are many solutions to do that, I've tried this one with StaticLayout:
#Override
public void draw (Canvas canvas, MapView mapView, boolean shadow){
super.draw(canvas, mapView, false);
if ( selectedPoint != null) {
// here you should define PopupText, textPaint and width variables
StaticLayout sl = new StaticLayout(popupText, textPaint, width,
Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
// here you can draw a rectangle — border for your popup text.
// You can use sl.getWidth() and sl.getWidth() methods to get the popup dimensions
canvas.save();
canvas.translate(selectedPoint.x, selectedPoint.y);
sl.draw(canvas);
canvas.restore()
}
}

Categories