I want to draw lines on the screen but my application is drawing only dotted. So what should I add in my code?
List<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLUE);
paint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
for (Point point : points) {
canvas.drawCircle(point.x, point.y, 5, paint);
// Log.d(TAG, "Painting: "+point);
}
}
public boolean onTouch(View view, MotionEvent event) {
// if(event.getAction() != MotionEvent.ACTION_DOWN)
// return super.onTouchEvent(event);
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
Log.d(TAG, "point: " + point);
return true;
}
}
class Point
{
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
Edit
Use drawLine or drawPath instead of drawCircle.
I would suggest you to take a look on the Fingerpaint example of the API Demos
Use drawLine bewteen 2 sets of points
For smoother lines, get all the historic events in onTouch and process them first
for faster/smoother, invalidate only the rect where points have changes
Read more here
Related
I've been trying to make a drawing canvas in my app, but I'm unable to draw the points precisely. I'm using an OnTouchListener and I add every point in the historical pointer to the canvas and paint it with black.
Unfortunately, it's not working because it's not drawing all the points touched by the user (for example, when tracing a line). I'll show you an example:
The code I'm using is the following:
public class DrawView extends View implements OnTouchListener {
List<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
}
public DrawView(Context context,AttributeSet attrs) {
super(context,attrs);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
}
public DrawView(Context context,AttributeSet attrs,int defStyle) {
super(context,attrs,defStyle);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLUE);
paint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
for (Point point : points) {
canvas.drawCircle(point.x, point.y, 12, paint);
}
}
public boolean onTouch(View view, MotionEvent event) {
Point point = new Point();
final int historySize = event.getHistorySize();
final int pointerCount = event.getPointerCount();
for (int h = 0; h < historySize; h++) {
for (int p = 0; p < pointerCount; p++) {
point.x=event.getHistoricalX(p, h);
point.y=event.getHistoricalY(p, h);
points.add(point);
invalidate();
Log.d("debug","pointer: "+
event.getPointerId(p)+" "+ event.getHistoricalX(p, h)+" "+ event.getHistoricalY(p, h));
}
}
/*point.x = (int)event.getX();
point.y = (int)event.getY();*/
Log.d("debug", "really saved: "+
event.getX()+" "+ event.getY());
//points.add(point);
//invalidate();
return true;
}
}
class Point {
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
Any ideas?
Thank you in advance
The problem is that you are only drawing points you get touch events for. If the user moves quickly you only get some of the points. The solution is to draw lines between consecutive points rather than just the points themselves.
You are missing many points here, you should capture all points here rather than capturing historical points only.
Check this -
http://www.codeproject.com/Articles/458042/Touch-handling-in-Android
I'm drawing a circle using 7 paint objects as below on a canvas in my android app. same paint object can be used more than one time to draw this circle.
Now I want to display color name of touched paint object, when user touch on each color.
How can I do this ?
Use on Touch Event for the same like :
public class TouchImage extends ImageView {
Paint paint = new Paint();
Point point = new Point();
public TouchImage(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setColor(Color.BLUE);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(point.x, point.y, 10, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
point.x = event.getX();
point.y = event.getY();
invalidate();
}
return true;
}
class Point {
float x, y;
}
}
You should have the positions for all color circles.
Inside onTouchEvent() you can compare the distance between each color circle and touch position with color circles radius.
If distance is less than radius (and maybe greater than min value, so only the colors are touchable and not the empty area inside circle) you could otbtain the angle and determine selected color this way.
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
for (colorCircle c : allCircles) {
float distance = sqrt ((event.getX() - c.getX())^2 +
((event.getY() - c.getY())^2);
if (distance < c.getRadius()) {
for (coloredPart cPart : c) {
if (event.getX() > (Math.cos(cPart.getMinAngle) * c.getRadius)
+ c.getX() &&
event.getX() < (Math.cos(cPart.getMaxAngle) * c.getRadius)
+ c.getX() &&
event.getY() > (Math.sin(cPart.getMinAngle) * c.getRadius)
+ c.getY() &&
event.getY() < (Math.sin(cPart.getMaxAngle) * c.getRadius)
+ c.getY() && ) {
// cPart was touched
}
}
}
}
}
return true;
}
Here is the code of a simple extension of an ImageView that allow the user to draw with the finger.
public class MyImageView extends ImageView {
List<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onDraw(Canvas canvas) {
for (Point point : points) {
canvas.drawCircle(point.x, point.y, 5, paint);
// Log.d(TAG, "Painting: "+point);
}
super.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
Log.d("", "point: " + point);
return true;
}
class Point {
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
}
This work pretty well.
Now, I want to use this code to draw at the top of a Bitmap.
I used:
MyImageView ivPic = (MyImageView) dialog.findViewById(R.id.ivPic);
ivPic.setImageBitmap(picture);
But the drawing is drawn "behind" the Bitmap:
Do you have any idea how I can draw at the "top" of the Bitmap?
I've changed the order in onDraw method, I put super.onDraw(canvas); at the beginning and I think it works now
override and use dispatchDraw Method, i used it to draw over views
I answer my own question, just found the answer:
ivPic.setBackgroundDrawable(new BitmapDrawable(getResources(),picture));
Don't know if that's the best practice but that works for me...
Change the sequence: first super.OnDraw(canvas) then your paint stuff
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Point point : points) {
canvas.drawCircle(point.x, point.y, 5, paint);
// Log.d(TAG, "Painting: "+point);
}
}
I have DrawView. If I touch this view it draws small circles. I wont to draw circles but not to touch view - with help function "setPoints". What I do:
package com.samples;
import ...
public class DrawView extends View {
ArrayList<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
private int pSize = 5;
private int pColor = Color.BLACK;
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
v.setOnTouchListener(this);
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
}
return true;
}
});
requestFocus();
}
#Override
public void onDraw(Canvas canvas) {
for (Point point : points) {
canvas.drawCircle(point.x, point.y, pSize, paint);
}
}
public void setPoints(Float xP, Float yP)
{
Point point = new Point();
point.x = xP;
point.y = yP;
points.add(point);
postInvalidate();
}
}
class Point {
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
Please tell me, how get canvas out setPoints function?
Update:
Wow, it's really interesting problem. My DrawView contains in HorizontalScrollView. Because if I set in this DrawView right coordinates, no one knows where are drawable circles.
You can't. The canvas is managed by the system and is passed to your onDraw(). I don't understand why you'd need it outside of there. Just redeclare setPoints like this
public void setPoints(Canvas canvas, Float xP, Float Yp)
You can keep a cache of the previous drawings (or store the previous points)
Try declaring canvas2 as a public variable in the DrawView class.
You draw your circles in onDraw(). That's the way View is supposed to work (technically it's actually in the draw() method but we'll overlook that). In setPoints(), set the points of the circle in variables within the class scope, call invalidate(), then draw the circle like that in onDraw(). If you follow this method, you're following the class flow that the view was designed for.
I want to display the coordinates of nodes which is placed on the view with the ontouch event, the coordinates are to be placed beside the circle nodes,temporarily i'm using (0,0) but i have no idea how to implement the real coordinates on the nodes properly,need some help.thanks
public class DrawView extends View implements OnTouchListener {
List<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
public DrawView(Draw context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.RED);
paint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
Paint rectanglePaint = new Paint();
rectanglePaint.setColor(Color.WHITE);
Paint layoutColor = new Paint();
layoutColor.setColor(Color.BLACK);
canvas.drawRect(new Rect(10,10,465,800), rectanglePaint);
canvas.drawLine(300, 10, 300, 800, layoutColor);
canvas.drawLine(0, 300, 465, 300, layoutColor);
// Paint textPaint = new Paint();
// textPaint.setColor(Color.CYAN);
// textPaint.setTextSize(30);
// canvas.drawText("Room", 220, 400, textPaint);
for (Point point : points) {
canvas.drawText("(0,0)", point.x+5, point.y+5, paint);
canvas.drawCircle(point.x, point.y, 5, paint);
// Log.d(TAG, "Painting: "+point);
}
}
final TextView textView = ( TextView )findViewById(R.id.textView1);
public boolean onTouch(View view, MotionEvent event) {
// return super.onTouchEvent(event);
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
return true;
}
}
Ahh, you don't really have a question about android. You have a java question. You want to know how to convert floats to strings.
This link will show you all you need to know: http://download.oracle.com/javase/tutorial/java/data/converting.html
String s = "(" + point.x + "," + point.y + ")";