Android触摸事件ACTION_MOVE的效率如何提高?

5

我目前正在开发一款允许自由绘图的应用程序。

我目前使用的方法如下:

currentLine是一个列表,它保留了所有ACTION_MOVE返回的点的历史记录。

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;

}

我会在我的类的onDraw方法中绘制这些点。

@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);
        }
    }

}

这种方法非常好,没有任何延迟。

但是,它并不能获得足够的点数。

例如,如果我快速地在整个屏幕上滑动手指,它可能只会绘制整个事件的15个点。

如何提高MotionEvent的性能/速度?如何获得更多的点?还是我应该做些其他的事情吗?

----编辑----

我已经自己解决了这个问题。

我放弃了使用drawCircle,转而使用drawLine

例如:

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);
        }
}

这会产生实线,这正是我想要的。

然而,为了增加知识,我仍然想知道如何加快MotionEvents的速度。

希望您能提供详细的答案。


我发现如果我持续进行"绘制"操作,不久之后事件数量会急剧增加。就好像Android注意到这个应用正在执行某些操作并为其分配了更多资源。我非常好奇是否有人能在这里提供一个有用的答案。 - Yevgeny Simkin
@Dr.Dredel,我已经更新了我的帖子,并提供了一个可能的解决方法,也许可以帮到你。 - MrZander
你是使用SurfaceView的扩展,还是普通的View? - Jave
一个普通的视图,但如果需要可以进行更换。 - MrZander
@MrZander:如果您将绘图移动到另一个线程(使用SurfaceView是一个不错的方法),它就不会阻塞MotionEvents,这样可以更频繁地触发。否则,您必须等待绘图完成才能获得新的MotionEvent。(很抱歉回答晚了,我没有收到您在我的问题上的回复通知) - Jave
显示剩余2条评论
4个回答

7

您还可以通过使用event.getHistoricalX/Y()函数来获得更多的点


希望能提供有关如何实现这个的更多信息。 - MrZander
请查看文档:http://developer.android.com/reference/android/view/MotionEvent.html,以及“Batching”部分。 - hackbod
我认为这是最有用的方法,实际上。 - Yevgeny Simkin

7
瓶颈在于绘图方法,这显而易见。 如果你正在处理Android 3.0+,请在GPU上绘制所有这些疯狂的东西。 添加属性即可。
android:hardwareAccelerated="true"

在您的清单文件中的<application>标签中添加以下内容,这将极大地增加绘制时间。

此外,如果只需要更新一点内容,请尝试不要重新绘制整个内容。使用invalidate(Rect dirty)而不是invalidate()。


我正在使用Android 2.2,但我会研究invalidate(Rect dirty)。谢谢。 - MrZander

0

invalidate(); 对性能有害。尝试计算边界矩形并调用 invalidate(bounds)


0
在动作事件中加入一个短小的线程休眠,这有助于解决当大量运动事件阻塞监听器时的问题。
Thread.sleep(100);

1
想要更多的事件。睡觉会如何帮助这个问题? - MrZander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接