Setting background colour for a SurfaceView in Android - 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:
Setting the background colour of my SurfaceView using android:background in XML.
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).
Setting the style of 2, to the parent view of the SurfaceView (a RelativeLayout).
Setting the style of 2, to the entire application, as a theme,using android:theme in my manifest file.
Setting the background drawable of my SurfaceView to an image which is plain and white-coloured.
Calling the setBackgroundColor for my SurfaceView from the code as, this.setBackgroundColor(Color.WHITE).
Thanks.

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.

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.

Related

how to mask a portion of GLSurfaceView in android

I have a custom GLSurfaceView that I want to mask a portion of.
Lets say I only want to draw a circular portion of it on screen.
I tried to override the dispathDraw method and use the clipPath method as suggested here
I ensured that the Hardware Acceleration is turned off but the GLsurfaceView renders without any change.
EDIT 1
I realized now that in android studio, after i hit run, the preview does update to show a clipped GLSurfaceView. The output on the screen remains rectangular.
EDIT 2
I figured that this only happens when the child view of the parent FrameLayout is GlSurfaceView. WHen I replace that with a imageview (containing blue background) it works as expected on the device.
Any suggestions?

Understanding the hidden cost of transparency on Android

I'm watching the video https://youtu.be/wIy8g8yNhNk
My first question.
As far as I understand from the video, when we draw a View that is opaque, we just put data, roughly speaking, a bitmap to the screen. That's called rendering. Is that right?
My second question.
Now let's draw a TextView with an opaque background an a semi-transparent text. Why should it be a two-step process as described in the video: we draw the TexView opaque and then apply a new alpha value to make text semi-transparent? Is it just the way Android was designed? Why can't we draw a semi-transparent pixel in one step?
My third question.
Here Ian Ne-Lewis's telling us about a view with two parts: opaque (on top) and semi-transparent (below the opaque part). He says the two parts don't overlap. But the opaque part is on top of the semi-transparent part. So why does he say these views don't overlap? As far as I understand, by "overlapping" he means having something semi-transparent on top of something opaque.
Answering your first question:
Rendering is the process executed by the Android Framework when it is drawing your opaque View on the screen.
Second Question
To render that TextView, Android will first draw the opaque background and then the semi-transparent Text. And as you saw on the video: When rendering alpha layers, android has to redraw the background layers to see what color should the alpha blend to.
That's just the way Android was designed. Even if both the background and the text were opaque, Android would first draw the background and then the text (but this time it doesn't need to check the background to blend).
Third Question
I think you didn't understand correctly the meaning of overlapping. Here's an example:

Make surface view transparent to current layout only

In my app i am using surface view for drawing perspective and some buttons on the same layout.
I am done with the drawing part but don't know how to make surface view transparent for the current layout only.
When i use holder.setFormat(PixelFormat.TRANSLUCENT); it shows my previous screen.
I have also tried the setZOrderOnTop(true); method but it makes my other buttons hidden/covered when drawing.
And using setZOrderMediaOverlay(true); put the view beyond current layout, if i am moving my finger over the screen it is drawing there as i can see the saved file, but not showing on screen.
I want to make it transparent for current screen without setting the z order.
Forks, help me to make this happen.
Thanks in advance.

Transparent SurfaceView over a transparent Activity

I have an Activity that is roughly 30-40% transparent which contains a custom View that extends SurfaceView. Everything is working as it should however the SurfaceView's background is not completely transparent (at least for the first few seconds). After 1-2 seconds (using debugger) I noticed the SurfaceView becomes completely transparent after onDraw is called from my Thread for the Canvas.
Now I'm assuming that the issue is; the canvas is selecting my activity's transparent background, creating a bitmap of it and then displaying it hence creating a double transparent overlay.
I've tried to initialize the SurfaceView first while the View is 'invisible' and enabled it after the first onDraw. No dice.
Any Suggestions or Questions?
My SurfaceView was Embedded within a RelativeLayout View Container. By applying the alpha parameter for this view to 255 resulted in what I was looking for.
I hope someone comes across the same situation, and that this has solved their problem.

How to add a text on the top of GLSurfaceview with transparent background in android?

Hi im having a parent viewgroup which has a background, contains a openglview as a part of that viewgroup.
What I want exactly is, i need a openglview with a transparent background and I want to able to see the parent background and I want to be able to write text on top of openglview, I dont want to use textures.
I tried this options,
Setting the openglview zorderontop as true. It makes my text to go behind the glview. If im not making zorderontop true, the background is black.
Setting the transluent theme to the activity which makes my glview and also the parent view group to become transparent.
I tried to inflate the layout contains the glview and use ContexThemeWrapper class to change the theme of the glview dynamically. But setTheme() not working at runtime. only applying theme in manifest file it works.
Applying the layout backgroud to transparent also didnt work, still black background.
The problem is that you're drawing to two separate surfaces: one surface created by ViewRoot, and one surface created for the GLSurfaceView. These surfaces are composited by SurfaceFlinger, one on top of the other. (By default the ViewRoot surface will be on top and the GLSurfaceView surface will be on bottom.)
Since all of your Views are drawn into the ViewRoot's surface, they must all be on top of the OpenGL surface or beneath the OpenGL surface.
If you don't want to use textures, period, your only choice is to create a third surface, this time with SurfaceView instead of GLSurfaceView, to draw your text above the GLSurfaceView.

Categories

Resources