2

I have a relative layout with several ImageViews (with transparent areas) above each other. The problem is: if I invalidate one of those, all other's onDraw() methods are called too. Is this normal? I don't want all Layers (Views) to redraw since this is a big performance issue- I only want the invalidated view to redraw..

Any ideas?

stoefln
  • 14,498
  • 18
  • 79
  • 138

2 Answers2

2

Assuming you're using invalidate() on your View, perhaps you can try one of the other ones instead? This would theoretically only redraw the affected (dirty) area.

void invalidate(Rect dirty)
void invalidate(int l, int t, int r, int b)
void invalidateDrawable(Drawable drawable)

See also this video (around the 34:07 mark). They have a nice little demo that describes this in detail.

Marvin Pinto
  • 30,138
  • 7
  • 37
  • 54
1

Is this normal?

Yes.

since this is a big performance issue

Use Traceview to identify where your performance bottleneck lies.

Or, possibly, really do use layers.

Or, if you are creating a game or something, don't use the widget framework, but instead directly draw to the Canvas (or use OpenGL).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Sorry, just to make sure: you are saying that e.g. if I have an animated button in one layout/view, overlapping a graphic layout/view (drawn in onDraw()), and i press the button (it animates...), the whole underlying graphic has to be drawn again? sounds weird to me- why is it that EACH view has an invalidate method then? ... – stoefln Jan 01 '12 at 22:46
  • @stoefln: "the whole underlying graphic has to be drawn again?" -- the scope of a redraw will be anything Android thinks may need to be redrawn, and Android tends to think things may need to be redrawn that you might not think so yourself. – CommonsWare Jan 01 '12 at 22:59
  • "Use Traceview to identify where your performance bottleneck lies." -> the bottleneck is the drawing of paths. I can't make this faster, all I would need is a possibility to cache the view, cause it only has to be drawn once (let's say when the app starts). "Or, possibly, really do use layers." -> This is not supported by android 2.1 "...instead directly draw to the Canvas" -> that's what I do. I draw to the canvas in onDraw() of the view, but as I said, this takes some processing, which I can't afford each time some component on another view is redrawn. – stoefln Jan 01 '12 at 23:33
  • @stoefln: "In all versions of Android, views have had the ability to render into off-screen buffers, either by using a view's drawing cache, or by using Canvas.saveLayer()." – CommonsWare Jan 02 '12 at 00:00
  • could you tell me how to use Canvas.saveLayer()? I read the documentation twice, but still have no clue how to make use of it. – stoefln Jan 02 '12 at 19:55
  • 1
    @stoefln: I haven't used it myself. See http://stackoverflow.com/questions/5121302/understanding-androids-canvas-savelayer -- AFAIK, drawing to your own bitmap seems to be more popular (http://stackoverflow.com/questions/2423327/android-view-ondraw-always-has-a-clean-canvas) – CommonsWare Jan 02 '12 at 20:00
  • Thanks- the hint with drawing your own cache bitmap, worked for me! – stoefln Jan 02 '12 at 20:55