I am trying to make a whiteboard in android. i am using the example suggested in here - Whiteboard Making
but this gives me everything in a dotted line. I want it to appear like a normal writing on a board. How can that be done.
In the canvas drawing routine, use lineTo instead of drawCircle.
Increase the radius of circle to higher values
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
for (Point point : points) {
canvas.drawCircle(point.x, point.y, 50, paint); //Here radius is 50
}
}
public boolean onTouch(View view, MotionEvent event) {
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
return true;
}
Related
I am developing an App that need to detect the stylus's size, for instance, if I use my hand(relatively wide) to draw, return null, if I use the stylus(relatively small) to draw, execute draw.Point method.
I have no idea how to detect this.
Please for help thanks.
My code list as below.
public PaintView(Context context) {
super(context);
paint=new Paint(Paint.DITHER_FLAG);
bitmap = Bitmap.createBitmap(MainActivity.widthPixels, MainActivity.heightPixels, Bitmap.Config.ARGB_8888);
canvas=new Canvas();
canvas.setBitmap(bitmap);
paint.setStyle(Paint.Style.STROKE);
//float size = paint.getStrokeWidth();
paint.setStrokeWidth(5);
paint.setColor(Color.RED);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap,0,0,null);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_MOVE) {
canvas.drawLine(mov_x, mov_y, event.getX(), event.getY(), paint);
invalidate();
}
if (event.getAction()==MotionEvent.ACTION_DOWN) {
mov_x=(int) event.getX();
mov_y=(int) event.getY();
canvas.drawPoint(mov_x, mov_y, paint);
invalidate();
}
mov_x=(int) event.getX();
mov_y=(int) event.getY();
return true;
}
You can use MotionEvent.getSize() method to detect sizes of finger and stylus touch and then create rule how to determine what caused the touch. Also MotionEvent.getPressure() may be useful.
I am creating a coaching board. I aim to draw a line between two points. Initial position is in the image below:
If I drag the chip away from the initial position, it should draw a line. When I move the chip, it should always draw a line.
This is what I tried:
case MotionEvent.ACTION_UP:
Toast.makeText(this, "here", Toast.LENGTH_SHORT).show();
Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
.getDefaultDisplay().getWidth(), (int) getWindowManager()
.getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(10);
int startx = 50;
int starty = 100;
int endx = 150;
int endy = 210;
canvas.drawLine(startx, starty, endx, endy, paint);
break;
I put that code inside the ontouchlistener of the chip.
You can download the project here: https://www.dropbox.com/s/ggfbsbkaokj9vxi/CoachingBoard.rar?dl=0
After further examining your code, I believe I have achieved what you'd like.
We're going to go to DrawingView and define a getter for drawCanvas, so we can access our canvas outside of the DrawingView class.
Next we're going to head to Basketball and do the following:
float startX;
float startY;
public boolean onTouch(View view, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getRawX();
startY = event.getRawY();
...
break;
case MotionEvent.ACTION_UP:
Paint paint = new Paint(); //set this as a field in drawView with another getter to avoid garbage collection penalties
paint.setStrokeWidth(15f);
paint.setColor(Color.BLACK);
drawView.getCanvas().drawLine(startX, startY, event.getRawX(), event.getRawY(), paint);
drawView.invalidate();
break;
}
}
What this does: when you pick up the chip it will save the starting coordinates, and when you drop the chip it will draw a line in your drawView canvas from start to end.
You can even draw the lines as a continuous Path so the lines always touch, but that is outside the context of this answer.
the best solution to draw a line by dragging is to get x and y positions from ACTION_DOWN and then get ever next x and y position from ACTION_MOVE, outside the switch statement, invalidate the canvas. draw the line with this starting x,y and ending x,y positions.
Code of these all explanation is below:
public class TouchEventView extends View {
float downxpos;
float downypos;
float upxpos;
float upypos;
private Paint paint = new Paint();
private Path path = new Path()
public TouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setColor(Color.GREEN);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawLine(downxpos, downypos, upxpos, upypos, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downxpos = event.getX();
downypos = event.getY();
case MotionEvent.ACTION_MOVE:
upxpos = event.getX();
upypos = event.getY();
break;
default:
return false;
}
invalidate();
return true;
}
}
hope this will help you and other community if you need more description feel free to ask.
I have to draw circle on screen and get interaction to it by OnTouch method. Kindly help me out. Here is the code that I have tried. Here the problem is that It does not intract with user interaction but this code successfully draw the circle
public class DrawingView extends View implements OnTouchListener {
static int x, y, r = 255, g = 255, b = 255;
final static int radius = 30;
Paint paint; // using this ,we can draw on canvas
public DrawingView(Context context) {
super(context);
paint = new Paint();
paint.setAntiAlias(true); // for smooth rendering
paint.setARGB(255, r, g, b); // setting the paint color
// to make it focusable so that it will receive touch events properly
setFocusable(true);
// adding touch listener to this view
this.setOnTouchListener(this);
}
// overriding the View's onDraw(..) method
public void onDraw(Canvas canvas) {
paint.setARGB(255, r, g, b);
super.onDraw(canvas);
// drawing the circle
canvas.drawCircle(x, y, radius, paint);
randColor(); // calls this method to generate a color before drawing
invalidate(); // calls onDraw method
}
// this is the interface method of "OnTouchListener"
public boolean onTouch(View view, MotionEvent event) {
x = (int) event.getX() - (radius / 2); // some math logic to plot the
// circle in exact touch place
y = (int) event.getY() - (radius / 2);
// System.out.println("X,Y:"+"x"+","+y); //see this output in "LogCat"
randColor(); // calls this method to generate a color before drawing
invalidate(); // calls onDraw method
return true;
}
// this method sets a random color using Math.random()
// Note: RGB color values ranges from 0 to 255..
public void randColor() {
r = (int) (Math.random() * 255);
g = (int) (Math.random() * 255);
b = (int) (Math.random() * 255);
// Toast.makeText(c, "r,g,b="+r+","+g+","+b,Toast.LENGTH_SHORT).show();
}
}
But the problem is that, it does not get user interaction
Simply use this to draw circle
public class Circle extends View {
private final float x;
private final float y;
private final int r;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public Circle(Context context, float x, float y, int r) {
super(context);
mPaint.setColor(0xFFFF0000);
this.x = x;
this.y = y;
this.r = r;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, r, mPaint);
}
For Interaction MainActivity class is here
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.circle);
FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
main.addView(new Circle(this, 50, 50, 25));
main.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent e) {
float x = e.getX();
float y = e.getY();
FrameLayout flView = (FrameLayout) v;
flView.addView(new Circle(flView.getContext(), x, y, 5));
return true;
}
});
}
At least a couple problems:
You've not actually tested wether the touch x/y fall inside the radius of the circle. You need an if clause. invalidate() now gets called with every touch.
The order of events is wrong and some operations are called too many times. Just this inside ondDraw should work:
super.onDraw(canvas);
paint.setARGB(255, r, g, b); // (and you don't need this in the method above)
canvas.drawCircle(x, y, radius, paint);
remove the invalidate() in onDraw() method, and get random color in onTouch().
you want different color in every touch action, place in touch(), or based touch down want to change the color then check the action from the event.getAction()==MotionEvent.ACTION_DOWN.
remove the invalidate() in onDraw() method because when you are invalidating in onDraw() it will call onDraw Recursivly, and get random color in onTouch().
you want different color in every touch action, place the random color method in onTouch(), or based touch down want to change the color then check the action from the event.getAction()==MotionEvent.ACTION_DOWN.
I have created a bar graph by drawing rectangles on a canvas. The only problem is that graph is upside down. I tried using the following code to flip the canvas right from the start, but this affects the onTouchEvent method in a weird way:
public void onDraw(final Canvas canvas) {
int width = super.getWidth();
int height = super.getHeight();
canvas.scale(1f, -1f,
width * 0.5f, height * 0.5f);
mCanvas = canvas;
super.onDraw(canvas);
....//more code after that
If the code above is implemented, the graph is shown properly. However, the x & y coordinates of the rectangles are inverted. This means that if I click the top of the canvas where there is no shape, the onTouchEvent method is still fired off because the point is where the rectangle would have been if the canvas wasn't flipped.
#Override
public boolean onTouchEvent( MotionEvent event) {
super.onTouchEvent(event);
int x = (int)event.getX();
int y = (int)event.getY();
xStored = x; yStored=y;
if (event.getAction()==MotionEvent.ACTION_UP){
}else if(event.getAction()==MotionEvent.ACTION_DOWN){
System.out.println("Touching down!");
if(!drawNew){
for(Rect rect : rectangles){
if(rect.contains(x,y)){
System.out.println("Touched Rectangle, start activity."+x+","+y);
drawNew = true;
invalidate();
}else{
}
}
}else{
drawNew = false;
invalidate();
}
}else if(event.getAction()==MotionEvent.ACTION_MOVE){
}
this.postInvalidate();
return true;
}
Whats the best way to flip the canvas upside-down while still preserving the onTouchEvent method?
It turns out that it is better to move and rotate the object on the canvas, rather than rotating the canvas itself.
I am trying to redraw an image on the canvas on an onTouch event. I am able to draw the image on the canvas, but I want the image to redraw at a particular x,y.
protected void onDraw(Canvas canvas)
{
mBitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.ab);
mBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.ab);
this.canvas=canvas;
Paint p = new Paint();
p.setColor(Color.parseColor("#FFFFFF"));
canvas.drawLine(x1, y1, x2 , y2, p);
canvas.drawBitmap(mBitmap1, 70, 60, null);
canvas.drawBitmap(mBitmap1, 185, 60, null);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
final int x=(int)event.getX();
Log.i("***********xPos","="+x);
final int y=(int)event.getY();
Log.i("***********yPos","="+y);
if(event.getAction()==MotionEvent.ACTION_UP)
{
}
if(event.getAction()==MotionEvent.ACTION_DOWN)
{
canvas.drawBitmap(mBitmap1,50+x,60,null );
this.postInvalidate();
}
if(event.getAction()==MotionEvent.ACTION_MOVE)
{
}
return false;
}
I think I understand your problem. You are calling postinvalidate() method each time when action.down is called, so it calls ultimately call ondraw(). So it will redraw it on bitmap for particular setted value at which you put in ondraw again.
So you looks that it remain unchanged.
Follow these steps:
use some public variables for drawing bitmaps in ondraw method for x and y axis, lets say initx and inity
then on touch event:update this value by adding your x and y value to initx and inity resp.
like:initx=initx+x;
inity=inity+y;
And last in cation down event just call post.invalidate or ondraw method.
See the MotionEvent class that provides the coordinates of where the user touched the screen.