Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onDraw Custom View inside a Scrollview

I have a custom view (width = 2000) inside a Horizontal Scrollview (width = 480). So there's a region that is scrollable.

When onDraw() is called, the dirty rectangle (returned by getClipBounds()) returns the whole view's dimensions, so I draw the whole view including the area that is not visible. As a consequence, when I scroll, onDraw() is not called any more, because the areas that become visible were already drawn and somehow remembered.

public void onDraw(Canvas canvas)
{
    canvas.getClipBounds(r); // returns 2000 x 400
}

This works fine!!!
However my custom view can be as wide as 20,000 or more, and things start to get slow. My concern is that the cached drawing uses a lot of memory. I don't think the drawing is being saved as bitmap because it would already have crashed, so how are these draw commands (lines and text, mostly) being saved? Is there a way to specify that onDraw() should only request the visible portion of the view, and when scrolling it keeps calling onDraw()? Or is there any other approach?

Thanks!

like image 607
Merlevede Avatar asked Mar 13 '14 03:03

Merlevede


1 Answers

Android uses hardware accelerated "display lists" for drawing since Android 3.0. This causes the display list for the whole view to be cached.

If the view within the ScrollView is really big you can disable hardware acceleration for the view.

We do this by subclassing ScrollView and overriding the onAttachedToWindow() method with this:

@Override
protected void onAttachedToWindow()
{
    setLayerType(LAYER_TYPE_SOFTWARE, null);
}
like image 196
HHK Avatar answered Oct 03 '22 08:10

HHK