Android -Measure the Coordinates of texts with the onTouchEvent coordinates - android

I want to dynamically update the Coordinate values of texts stored in an array when MotionEvent.ACTION_MOVE triggers
The problem is i can manually change the Coordinates, But how to measure the Coordinates of Texts and Coordinates of Event.
package argha.paperzone.papereditor.paperviews;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import argha.paperzone.papereditor.models.PaperTextModel;
public class PaperEditorView extends View {
private Paint paint;
private List<PaperTextModel> textModelList = new ArrayList<>();
public PaperEditorView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTextSize(60);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
}
public void addText(String text) {
if (textModelList.size() == 0) {
textModelList.add(new PaperTextModel(1, 100, 100));
} else {
int lastId = textModelList.get(textModelList.size() - 1).getId();
int lastX = textModelList.get(textModelList.size() - 1).getXAxis();
int lastY = textModelList.get(textModelList.size() - 1).getYAxis();
textModelList.add(new PaperTextModel(lastId + 1, lastX, lastY + 100));
}
invalidate();
}
public void clearAll() {
textModelList.clear();
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (textModelList.size() > 0) {
for (int i = 0; i < textModelList.size(); i++) {
canvas.drawText("Text " + textModelList.get(i).getId(),
textModelList.get(i).getXAxis(),
textModelList.get(i).getYAxis(),
paint
);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventAction = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
switch (eventAction) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
textModelList.get(2).setXAxis(x);
textModelList.get(2).setYAxis(y);
}
invalidate();
return true;
}
}

Related

Changing path color without changing previous paths

I made straight lines with the canvas.drawPath command. But now I want that the color is selectable. So you click on a button and afterwards, the path is in this color, but the previous paths remain in their colors.. The thin with the button comes later, the colour is random at the moment...
I did it, i changed the code from here! Change path color without changing previous paths
Main Activity
package com.example.drawproject;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DrawArea da = new DrawArea(this);
setContentView(da);
}
}
Draw Activity
import android.content.Context;
import android.graphics.*;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class DrawArea extends View {
private List<Stroke> _allStrokes; //all strokes that need to be drawn
private SparseArray<Stroke> _activeStrokes; //use to retrieve the currently drawn strokes
private Random _rdmColor = new Random();
int count = 1;
public DrawArea(Context context) {
super(context);
_allStrokes = new ArrayList<Stroke>();
_activeStrokes = new SparseArray<Stroke>();
setFocusable(true);
setFocusableInTouchMode(true);
}
public void onDraw(Canvas canvas) {
if (_allStrokes != null) {
for (Stroke stroke: _allStrokes) {
if (stroke != null) {
Path path = stroke.getPath();
Paint painter = stroke.getPaint();
if ((path != null) && (painter != null)) {
if(count%2 != 0){
canvas.drawPath(path, painter);
}
}
}
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
final int pointerCount = event.getPointerCount();
switch (action) {
case MotionEvent.ACTION_DOWN: {
count++;
if(count%2 != 1)
{pointDown((int)event.getX(), (int)event.getY(), event.getPointerId(0));
break;
}
if (count%2 != 0){
for (int pc = 0; pc < pointerCount; pc++) {
pointDown((int)event.getX(pc), (int)event.getY(pc), event.getPointerId(pc));
}
}
}
case MotionEvent.ACTION_MOVE: {
break;
}
case MotionEvent.ACTION_UP: {
break;
}
}
invalidate();
return true;
}
private void pointDown(int x, int y, int id) {
if(count%2 !=1){
//create a paint with random color
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10);
paint.setColor(_rdmColor.nextInt());
//create the Stroke
Point pt = new Point(x, y);
Stroke stroke = new Stroke(paint);
stroke.addPoint(pt);
_activeStrokes.put(id, stroke);
_allStrokes.add(stroke);
}
if (count%2 != 0){
//retrieve the stroke and add new point to its path
Stroke stroke = _activeStrokes.get(id);
if (stroke != null) {
Point pt = new Point(x, y);
stroke.addPoint(pt);
}
}
}
}
Lines
package com.example.drawproject;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
public class Stroke {
private Path _path;
private Paint _paint;
public Stroke (Paint paint) {
_paint = paint;
}
public Path getPath() {
return _path;
}
public Paint getPaint() {
return _paint;
}
public void addPoint(Point pt) {
if (_path == null) {
_path = new Path();
_path.moveTo(pt.x, pt.y);
} else {
_path.lineTo(pt.x, pt.y);
}
}
}
For each path declare separate paint object and change paint object of the path that you want to change.
canvas.drawPath(path1, paint1);
canvas.drawPath(path2, paint2);
canvas.drawPath(path3, paint3);
canvas.drawPath(path4, paint4);
The main idea:
public class temp extends View{
private Map<Path,Paint> MyMap = new HashMap<Path,Paint>();
public ViewFeld(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
private void init() {
for (int i = 0; i < number of pathes ; i++) {
Path path = new Path();
paint = new Paint();
paint.setColor(Color.MAGENTA);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.FILL);
MyMap.put(path, paint);
}
}
protected void onDraw(Canvas canvas) {
for (Path p : MyMap.keySet()) {
canvas.drawPath(p, MyMap.get(p));
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Paint p = MyMap.get(path you want to change the color);
// change the color of p
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
// nothing to do
break;
default:
return false;
}
// Schedules a repaint.
invalidate();
return true;
}

Move ball back and forth

Trying to get the ball where it moves back and forth across the screen (left-right).
I tried using the draw function to update the ball position using if statements
x += speed_x;
y += speed_y;
canvas.drawCircle(x, y, 20, paint);
if (x == 0)
speed_x=-1;
if (x == getHeight())
speed_x=1;
if (y == 0)
speed_y = -1;
if (y == getWidth())
speed_y = 1;
invalidate();
This did not work.
**game.java*
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.ImageView;
public class GameWorld extends SurfaceView implements Runnable {
boolean isRunning;
GameObject obj;
SurfaceHolder holder;
Canvas canvas;
Thread gameThread;
Paint paint;
private Context mContext;
int x = -1;
int y = -1;
int speed_x=1, speed_y=1;
private int xVelocity = 10;
private int yVelocity = 5;
private Handler h;
private final int FRAME_RATE = 30;
public GameWorld(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
h = new Handler();
}
private Runnable r = new Runnable() {
#Override
public void run() {
invalidate();
}
};
public GameWorld(Context context){
super(context);
isRunning=true;
obj=new GameObject(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher),200,300);
paint=new Paint();
gameThread= new Thread(this);
gameThread.start();
holder=getHolder();
}
public void run(){
while(isRunning){
if(!holder.getSurface().isValid()){
continue;
}
update();
draw();
}
}
private void update(){
obj.update();
}
private void draw(){
canvas=holder.lockCanvas();
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
obj.draw(canvas);
canvas.drawColor(Color.WHITE);
x+=speed_x;
y+=speed_y;
canvas.drawCircle(x, y, 20, paint);
if(x==0)
speed_x=-1;
if(x== getHeight())
speed_x=1;
if(y==0)
speed_y=-1;
if(y==getWidth())
speed_y=1;
invalidate();
holder.unlockCanvasAndPost(canvas);
}
public boolean onTouchEvent(MotionEvent event){
obj.jump();
return super.onTouchEvent(event);
}
}
**main:**
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GameWorld(this));
}
}
**gameobject.java**
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
public class GameObject {
int x,y;
int velY;
int width, height;
boolean jump;
Bitmap bitmap;
final int GRAVITY =2;
public GameObject(Bitmap bitmap, int x, int y){
this.x=x;
this.y=y;
this.width=bitmap.getWidth();
this.height=bitmap.getHeight();
this.bitmap=bitmap;
velY=0;
jump=false;
}
public void update(){
//handles input
if (jump){
velY=-30;
}
//add gravity
velY+=GRAVITY;
y+=velY;
//POSITION
if(y>300){
y=300;
velY=0;
}
jump=false;
}
public void jump(){
jump=true;
}
Paint paint = new Paint();
public void draw(Canvas canvas){
canvas.drawBitmap(bitmap,x,y,null);
int x=5; //ball
boolean game = true;
// while(game = true)
// {
int maxx = canvas.getWidth();
if (x <= maxx)
{
paint.setColor(Color.WHITE);
canvas.drawCircle(x, 305, 10, paint);
x= (x+2);
}
///else{
// x= (x-2);
// paint.setColor(Color.WHITE);
// canvas.drawCircle(x, 305, 10, paint);
// game = false;
//}
// }
}
public void moveball()
{
x= (x-2);
}
}
Here is my version of a ball moving based on the swipes it recives
import android.app.Activity;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.View;
public class BouncingBallActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View boundcingBallView = new BouncingBallView(this);
setContentView(boundcingBallView);
}
}
Here is the actual view that will make the ball
package com.example.bouncingball;
import java.util.Formatter;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class BouncingBallView extends View {
private int xMin=0,xMax,yMin=0,yMax;
private float ballRadius = 80,ballX = ballRadius+20, ballY= ballRadius+40,ballSpeedX=5,ballSpeedY=3,previousX,previousY;
private RectF ballBounds;
private Paint paint;
private StringBuilder statusmsg = new StringBuilder();
private Formatter formatter = new Formatter(statusmsg);
public BouncingBallView(Context context) {
super(context);
ballBounds = new RectF();
paint = new Paint();
paint.setDither(true);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setHinting(Paint.HINTING_ON);
paint.setPathEffect(new DashPathEffect(new float[] {1,1}, 0));
paint.setTypeface(Typeface.MONOSPACE);
paint.setTextSize(16);
this.setFocusableInTouchMode(true);
}
#Override
protected void onDraw(Canvas canvas) {
ballBounds.set(ballX-ballRadius , ballY-ballRadius,ballX+ballRadius,ballY+ballRadius);
paint.setColor(Color.GREEN);
canvas.drawOval(ballBounds, paint);
paint.setColor(Color.BLACK);
canvas.drawText(statusmsg.toString(), 10, 30,paint);
update();
invalidate();
}
private void update() {
ballX +=ballSpeedX;
ballY+=ballSpeedY;
if(ballX+ballRadius> yMax) {
ballSpeedX =-ballSpeedX;
ballX = xMax -ballRadius;
}
else if(ballX - ballRadius < xMin) {
ballSpeedX = -ballSpeedX;
ballX = xMin+ballRadius;
}
if(ballY + ballRadius > yMax) {
ballSpeedY = -ballSpeedY;
ballY = yMax-ballRadius;
}
else if (ballY - ballRadius < yMin) {
ballSpeedY = -ballSpeedY;
ballY = yMin+ballRadius;
}
statusmsg.delete(0, statusmsg.length());
formatter.format("Ball#(%3.0f,%3.0f),Speed=(%2.0f,%2.0f)", ballX, ballY,ballSpeedX, ballSpeedY);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
xMax = w-1;
yMax = h-1;
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) {
case KeyEvent.KEYCODE_DPAD_RIGHT:
ballSpeedX++;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
ballSpeedX--;
break;
case KeyEvent.KEYCODE_DPAD_UP:
ballSpeedY--;
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
ballSpeedY++;
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
ballSpeedX = 0;
ballSpeedY = 0;
break;
case KeyEvent.KEYCODE_A:
float maxRadius = (xMax > yMax) ? yMax / 2* 0.9f : xMax / 2 * 0.9f;
if(ballRadius < maxRadius)
ballRadius*=1.05;
break;
case KeyEvent.KEYCODE_Z:
if(ballRadius>20){
ballRadius *=0.95;
}
break;
}
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float currentX=event.getX();
float currentY = event.getY();
float deltaX,deltaY;
float scalingFactor = 5.0f / ((xMax > yMax) ? yMax : xMax);
switch(event.getAction()) {
case MotionEvent.ACTION_MOVE:
deltaX = currentX - previousX;
deltaY = currentY - previousY;
ballSpeedX += deltaX*scalingFactor;
ballSpeedY += deltaY*scalingFactor;
}
previousX = currentX;
previousY = currentY;
return true;
}
}

Android Canvas Undo and Redo with Bitmap

I'm having problem with undo and redo operations on a canvas.
I noticed the below code works if I don't use canvas.drawbitmap in the Ondraw() method but I need to draw to bitmap so I can save canvas image and as well load image. Kindly help me.
Below is my code.
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.akinslove.drawingapp.activities.DrawingCanvasActivity;
public class DrawView extends View {
// for bitmap
private Bitmap mainBitmap;
private Canvas mainCanvas;
private Paint mainbitmapPaint;
// for canvas
private Path currentPath;
private Paint currentpathPaint;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialiseMyComponents();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
initialiseMyComponents();
}
public DrawView(Context context) {
super(context);
initialiseMyComponents();
}
private void initialiseMyComponents() {
currentPath = new Path();
currentpathPaint = new Paint();
currentpathPaint.setColor(Color.BLACK);
currentpathPaint.setStrokeWidth(10);
currentpathPaint.setStyle(Style.STROKE);
currentpathPaint.setStrokeJoin(Join.ROUND);
currentpathPaint.setStrokeCap(Cap.ROUND);
currentpathPaint.setAntiAlias(true);
mainbitmapPaint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
for (Path p : paths){
canvas.drawPath(p, currentpathPaint);
}
canvas.drawPath(currentPath, currentpathPaint);
**//I wish to use the below line of code
canvas.drawBitmap(mainBitmap, 0, 0, mainbitmapPaint);**
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (mainBitmap == null) {
mainBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
mainCanvas = new Canvas(mainBitmap);
mainCanvas.drawColor(Color.WHITE);
}
}
float lastX;
float lastY;
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
float x = event.getX();
float y = event.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
undonePaths.clear();
DrawingCanvasActivity.IMAGEDRAWN = true;
currentPath.moveTo(x, y);
lastX = x;
lastY = y;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
currentPath.quadTo(lastX, lastY, (lastX + x) / 2, (lastY + y) / 2);
mainCanvas.drawPath(currentPath, currentpathPaint);
lastX = x;
lastY = y;
invalidate();
break;
case MotionEvent.ACTION_UP:
currentPath.lineTo(x, y);
mainCanvas.drawPath(currentPath, currentpathPaint);
// kill this so we don't double draw
paths.add(currentPath);
currentPath = new Path();
currentPath.rewind();
invalidate();
break;
}
return true;
}
// method to get bitmap
public Bitmap getMainBitmap() {
return mainBitmap;
}
// method to set bitmap
public void setMainBitmap(Bitmap mpt) {
mainBitmap = mpt;
mainCanvas = new Canvas(mainBitmap);
postInvalidate();
}
public void onClickUndo () {
if (paths.size()>0)
{
undonePaths.add(paths.remove(paths.size()-1));
invalidate();
}
}
public void onClickRedo (){
if (undonePaths.size()>0)
{
paths.add(undonePaths.remove(undonePaths.size()-1));
invalidate();
}
}
}
I just found out that the line mainCanvas.drawPath(currentPath, currentpathPaint); at both case MotionEvent.ACTION_UP: and case MotionEvent.ACTION_MOVE: should not be there. It seems to redraw the path to bitmap and onto the canvas. Not sure if I speak the right android terms.

Android Canvas drawLine

I have a custom layout to draw a line based on touch input. I have it drawing the line but when the user touches the screen, the line disapeers and it draws a new line. What I want it to do is to draw a new line and leave the previous line there.
Here is my code:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
float startX;
float startY;
float stopX;
float stopY;
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawLine(startX, startY, stopX, stopY, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
return true;
case MotionEvent.ACTION_MOVE:
stopX = event.getX();
stopY = event.getY();
break;
case MotionEvent.ACTION_UP:
stopX = event.getX();
stopY = event.getY();
break;
default:
return false;
}
Invalidate();
return true;
}
}
You need to store all the lines instead of just the last one.
The following code is completely untested, but hopefully gives you the general idea.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
class Line {
float startX, startY, stopX, stopY;
public Line(float startX, float startY, float stopX, float stopY) {
this.startX = startX;
this.startY = startY;
this.stopX = stopX;
this.stopY = stopY;
}
public Line(float startX, float startY) { // for convenience
this(startX, startY, startX, startY);
}
}
public class DrawView extends View {
Paint paint = new Paint();
ArrayList<Line> lines = new ArrayList<Line>();
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
}
#Override
protected void onDraw(Canvas canvas) {
for (Line l : lines) {
canvas.drawLine(l.startX, l.startY, l.stopX, l.stopY, paint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
lines.add(new Line(event.getX(), event.getY()));
return true;
}
else if ((event.getAction() == MotionEvent.ACTION_MOVE ||
event.getAction() == MotionEvent.ACTION_UP) &&
lines.size() > 0) {
Line current = lines.get(lines.size() - 1);
current.stopX = event.getX();
current.stopY = event.getY();
invalidate();
return true;
}
else {
return false;
}
}
}

How to achieve multitouch for whole activity?

I have one activity which is having linear layout and inside this layout there are several linear layouts and each linear layout is having set if buttons and text views. I want to achieve multi touch feature for whole screen means if user perform zoom in-zoom out using his finger then it should zoom in and zoom out whole screen(increase and decrease all buttons,text views size accordingly once).
How to achieve it using android 2.1?
regards,
Piks
This might give you an idea:
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
//import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
public class MultitouchView extends View {
private static final int STROKE_WIDTH = 1;
private static final int CIRCLE_RADIUS = 20;
private ArrayList<PointF> touchPoints = null;
private Paint drawingPaint = null;
private boolean isMultiTouch = false;
private int pathEffectPhase = 0;
public MultitouchView(Context context) {
super(context);
initialize(context);
}
public MultitouchView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize(context);
}
public MultitouchView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(touchPoints.size() > 0)
{
DashPathEffect effect = new DashPathEffect(new float[] {7,7}, pathEffectPhase);
PointF midpt = null;
drawingPaint.setPathEffect(effect);
for(int index=1; index<touchPoints.size(); ++index)
{
midpt = getMidPoint(
touchPoints.get(index - 1).x,touchPoints.get(index - 1).y,
touchPoints.get(index).x,touchPoints.get(index).y);
canvas.drawCircle(
touchPoints.get(index - 1).x,touchPoints.get(index - 1).y,
1, drawingPaint);
canvas.drawCircle(
touchPoints.get(index - 1).x,touchPoints.get(index - 1).y,
CIRCLE_RADIUS, drawingPaint);
canvas.drawCircle(touchPoints.get(index).x,touchPoints.get(index).y,
1, drawingPaint);
canvas.drawCircle(touchPoints.get(index).x,touchPoints.get(index).y,
CIRCLE_RADIUS, drawingPaint);
canvas.drawLine(
touchPoints.get(index - 1).x,touchPoints.get(index - 1).y,
touchPoints.get(index).x,touchPoints.get(index).y,
drawingPaint);
canvas.drawCircle(midpt.x,midpt.y, 10, drawingPaint);
}
++pathEffectPhase;
invalidate();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
int action = event.getAction() & MotionEvent.ACTION_MASK;
switch(action)
{
case MotionEvent.ACTION_DOWN:
{
invalidate();
break;
}
case MotionEvent.ACTION_POINTER_DOWN:
{
isMultiTouch = true;
setPoints(event);
invalidate();
break;
}
case MotionEvent.ACTION_POINTER_UP:
{
isMultiTouch = false;
break;
}
case MotionEvent.ACTION_MOVE:
{
if(isMultiTouch)
{
setPoints(event);
invalidate();
}
break;
}
}
return true;
}
private void initialize(Context context){
drawingPaint = new Paint();
drawingPaint.setColor(Color.RED);
drawingPaint.setStrokeWidth(STROKE_WIDTH);
drawingPaint.setStyle(Paint.Style.STROKE);
drawingPaint.setAntiAlias(true);
touchPoints = new ArrayList<PointF>();
}
public void setPoints(MotionEvent event){
touchPoints.clear();
int pointerIndex = 0;
for(int index=0; index<event.getPointerCount(); ++index)
{
pointerIndex = event.getPointerId(index);
touchPoints.add(new PointF(event.getX(pointerIndex),event.getY(pointerIndex)));
}
}
private PointF getMidPoint(float x1,float y1, float x2, float y2) {
PointF point = new PointF();
float x = x1 + x2;
float y = y1 + y2;
point.set(x / 2, y / 2);
return point;
}
}

Categories

Resources