Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android MotionEvent ACTION_MOVE efficiency. How to improve performance?

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

like image 851
MrZander Avatar asked Dec 13 '11 04:12

MrZander


People also ask

What is MotionEvent in Android?

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.

How do I use onTouchEvent on Android?

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.

What is Action_down?

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.

How do you make a motion event on android?

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).


2 Answers

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().

like image 72
poitroae Avatar answered Oct 29 '22 20:10

poitroae


You should also get more points by utilizing event.getHistoricalX/Y() functions

like image 42
Sameer Avatar answered Oct 29 '22 20:10

Sameer