Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting background colour for a SurfaceView in Android

I am building a paint application for android. Extending the FingerPaint application sample provided with the SDK. However, unlike FingerPaint, I'm using SurfaceView with a separate rendering thread to draw to the surface. All this is very standard and straightforward. Working well. I want to, however, give a White coloured background to the painting surface, so it's like drawing on a white paper. The default background is black coloured. The thread of my surface view, calls the onDraw() method of the view.

The problem I'm facing here is, if I set a background colour or background resource to my SurfaceView, this background overwrites the previous drawing of the surface, when the view is rendered the next time. I will explain this with an example:

Suppose I set the background to white colour. Now, the application starts, with my SurfaceView having the white colour. Ok, so far good. Now, I draw a red coloured line on this surface, with my finger. The line is now shown on the white surface. Good. Now, this is supposed to be a painting app, and suppose I want to draw a car. So, then, I draw my 2nd red line, with my finger. The 2nd line is drawn on the screen, but the 1st one, which I drew previously, vanishes. That is, because I have set some background to my SurfaceView, the background is drawn again, thus overwriting the 1st line that was drawn. Now the screen shows only the 2nd line drawn.

Obviously, I do not want this to happen. The code works perfectly, when I don't attempt to change the background (that is, both lines are shown, on a default black background, no background effectively). But when I set some desired background, this thing happens. Is there a way to somehow have a static background, that is not drawn every time? I want the background to be drawn only once, all the subsequent drawings should happen on this background. I don't want the android runtime , to draw the background, every time it draws my view, thus overwriting all drawing present on that view, from previous renderings. Any way to work around this?

The things I have tried, to achieve this are:

  1. Setting the background colour of my SurfaceView using android:background in XML.

  2. Doing the above, using the concept of style. (specifying a style value and referencing it in the layout file). The style just defines the background colour as #FFFFFFFF (white).

  3. Setting the style of 2, to the parent view of the SurfaceView (a RelativeLayout).

  4. Setting the style of 2, to the entire application, as a theme,using android:theme in my manifest file.

  5. Setting the background drawable of my SurfaceView to an image which is plain and white-coloured.

  6. Calling the setBackgroundColor for my SurfaceView from the code as, this.setBackgroundColor(Color.WHITE).

Thanks.

like image 596
sanjeev mk Avatar asked Dec 15 '11 08:12

sanjeev mk


People also ask

How do I make the background a view color?

To get background color of a Layout: LinearLayout lay = (LinearLayout) findViewById(R. id. lay1); ColorDrawable viewColor = (ColorDrawable) lay.


2 Answers

according to android's doc:

The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes

so if you change the z order of surface view via:

setZOrderOnTop(true);

this will work, but then you cannot put any other view on top of surface view.

like image 176
disorderdev Avatar answered Oct 06 '22 06:10

disorderdev


Now I also tried overlaying my SurfaceView over another View with a white background, and setting the SurfaceView to be fully transparent. I used FrameLayout for this. That is, a View with a white background, overlayed upon which is my SurfaceView set to fully transparent.

This also failed to work. So now I have come to conclusion that the background colour of SurfaceView cannot be changed. So now I have dropped SurfaceView, and using a normal view, instead for my drawings. So far, there has not been any performance loss observed. But, it feels kind of wrong to drop an efficient implementation , just because SurfaceView doesn't let me change it's background colour.

like image 38
sanjeev mk Avatar answered Oct 06 '22 04:10

sanjeev mk