I am currently working on an app that allows for free-drawing.
The current method I am using is as follows:
currentLine is a list that keeps a history of all points that ACTION_MOVE
returns.
public boolean onTouchEvent (MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
Point p = new Point(event.getX(),event.getY());
currentLine.addPoint(p);
invalidate();
break;
}
return true;
}
I then take these points and draw them in the onDraw
method of my class.
@Override
protected void onDraw(Canvas c) {
super.onDraw(c);
//Draw Background Color
c.drawColor(Color.BLUE);
//Setup Paint
Paint p = new Paint();
p.setStyle(Style.FILL);
p.setColor(COLOR.WHITE);
//iterate through points
if(currentLine.size()>0){
for(int x = 0;x<currentLine.size();x++){
c.drawCircle(currentLine.get(x).getX(), currentLine.get(x).getY(), 3, p);
}
}
}
And this method works great, with no lag or anything.
Except, it does not get enough of the points that it needs to.
For example, if I am to drag my finger quickly across the entire screen, it may only draw 15 points of the whole event.
How can I improve the performance/speed of the MotionEvent? How can I get more points? Or is there something else I should be doing?
----EDIT----
I have managed to solve it myself.
Instead of using drawCircle
, I switched to drawLine
.
Example:
if(points.size()>0){
for(int x = 0;x<points.size()-1;x++){
c.drawLine(points.get(x).getX(), points.get(x).getY(), points.get(x+1).getX(), points.get(x+1).getY(), p);
}
}
This produces solid lines, which is what I wanted.
However, for the sake of knowledge, I would still like to know how to speed up MotionEvents.
A detailed answer would be appreciated
android.view.MotionEvent. Object used to report movement (mouse, pen, finger, trackball) events. Motion events may hold either absolute or relative movements and other data, depending on the type of device.
After the Math. abs() calls, you're essentially testing if their finger is farther down the screen than it is across the screen. Store the initial down coordinates as member variables and set them during ACTION_DOWN . You declared two floats (touchX and touchY) inside the onTouchEvent method.
ACTION_DOWN is for the first finger that touches the screen. This starts the gesture. The pointer data for this finger is always at index 0 in the MotionEvent. ACTION_POINTER_DOWN is for extra fingers that enter the screen beyond the first.
You should use one of the static obtain methods of the MotionEvent class to create a new event. API Docs: Create a new MotionEvent, filling in a subset of the basic motion values. Those not specified here are: device id (always 0), pressure and size (always 1), x and y precision (always 1), and edgeFlags (always 0).
The bottleneck is the drawing method, obviously.
If you are working on android 3.0+, draw all those crazy things on the GPU. Add the attribute
android:hardwareAccelerated="true"
to the <application>
tag in your manifest. This will unbelievably increase drawing time.
Additionally, try to not redraw the whole thing if only a little needs to be updated. Invoke invalidate(Rect dirty) instead of invalidate().
You should also get more points by utilizing event.getHistoricalX/Y() functions
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With