使用invalidate(Rect dirtyRect)实现交互式画布时导致的延迟

时间:2012-06-01 19:31:54

标签: android graph plot invalidation

我正在使用GraphView API,并且我已经将图表实现为难以处理。当用户触摸图形时,会出现一条垂直线,从数据点延伸到图形的底部。

我在onDraw方法中创建了这样的行:

mDrawable = new ShapeDrawable(new RectShape());
mDrawable.getPaint().setColor(0xFF363636);
mDrawable.setBounds((int)markerX,(int) (markerY) , (int)markerX+1,  (int) height);
mDrawable.draw(canvas);

我使用以下代码以及用于计算标记位置的代码来刷新onTouch方法中的行。

invalidate(mDrawable.getBounds());

移动drawable时出现问题。如果手势足够快,则往往会有刷新延迟并且线条在图表上消失(几分之一秒)。该线与运动保持一致,但它消失了。看起来几乎就像物品的移动速度快于它的界限,如果这有任何意义的话。

我听说整个画布无效是一个禁忌,并且使你想要改变的界限无效(我上面做了什么)。当整个画布无效时,消失的线条现象不会发生,但应用确实运行缓慢。

我对SurfaceView和表面支架做了一些神奇的事情,但在这种情况下使用它们似乎反效果。根据我的理解,我基本上将使用invalidate()方法,但在不同的线程中。所有东西仍然会重新绘制,这似乎适得其反。

是否有其他方法可以实现GraphView库中描述的效果?

1 个答案:

答案 0 :(得分:1)

我能够通过简单的修复来解决这个问题。无论何时更改屏幕,移动(移植模式)或触摸(横向模式),都会调用onDraw()方法。虽然使用了脏的Rect方法(横向模式),但它仍然有明显的滞后。在滚动视图中滚动图形时,也存在明显的延迟。解决方案是将画布保存到位图(在第一次调用时),存储位图,然后仅在位图顶部之后绘制标记。每当更改视口或添加不同的数据集时,位图都将无效以绘制所有数据。代码

    protected void onDraw(Canvas sysCanvas) {
         canvas = new Canvas(); 

         if (bitmap != null) { 
                sysCanvas.drawBitmap(bitmap, 0,0, null); 
                drawMarker(sysCanvas); //draw whatever you want to the system canvas in a different method
                return; 
         } 


        bitmap = Bitmap.createBitmap(sysCanvas.getWidth(), sysCanvas.getHeight(), Bitmap.Config.ARGB_8888); 
        canvas.setBitmap(bitmap); 

        ///more code, draw whatever you want to canvas.
        sysCanvas.drawBitmap(bitmap,0, 0,null);
    } 

第一次运行后,画布将绘制图形。在第一次传递之后,画布只绘制位图,然后转到绘制对象的方法。这些对象具有在onTouch()方法中设置的x和y参数。

此方法彻底可提高性能。在我的例子中,我在scrollView(纵向模式)中有一个图形。每当滚动视图向任一方向移动时,都会重绘画布。这种不断的重绘真的吃了资源。绘制我实施的标记(跟随你的手指的圆圈)也是如此。由于CPU只需重绘2个对象,因此花费的时间越少,性能就越高。

希望这有帮助!